登陆 | 注册 | 留言 | 设首页 | 加收藏
当前位置: 网站首页 > 前沿技术 > 文章 当前位置: 前沿技术 > 文章

大数据国产化迁移通用方案

时间:2024-08-19    点击: 次    来源:网络    作者:佚名 - 小 + 大

1. 数据库和程序的解决方案
1.1. Oracle数据库函数切换pg方案(自定义pg函数与view方式)
1.1.1. 转换sys_guid()
pg_sys_guid()
CREATE or REPLACE FUNCTION "sys_guid"()
RETURNS "pg_catalog"."varchar" AS
$BODY$
DECLARE
 v_seed_value varchar(32);
BEGIN
select
md5(
inet_client_addr()::varchar ||
timeofday() ||
inet_server_addr()::varchar ||
to_hex(inet_client_port())
)
into v_seed_value;
 
 
return (substr(v_seed_value,1,8) ||
substr(v_seed_value,9,4) ||
substr(v_seed_value,13,4) ||
substr(v_seed_value,17,4) ||
substr(v_seed_value,21,12));
END;
$BODY$
LANGUAGE plpgsql VOLATILE SECURITY DEFINER;
1.1.2. orcale-decode函数
---------------------------------字符串decode函数---------------------------------------------------
create or replace function decode(variadic p_decode_list text[])
returns text
as
$$
declare
-- 获取数组长度(即入参个数)
v_len integer := array_length(p_decode_list, 1);
-- 声明存放返回值的变量
v_ret text;
begin
/*
* 功能说明:模拟Oracle中的DECODE功能(字符串处理, 其它格式可以自行转换返回值)
* 参数说明:格式同Oracle相同,至少三个参数
* 实现原理: 1、VARIADIC 允许变参; 2、Oracle中的DECODE是拿第一个数依次和之后的偶数位值进行比较,相同则取偶数位+1的数值,否则取最后一位值(最后一位为偶数为,否则为null)
*/
 
-- 同Oracle相同当参数不足三个抛出异常
if v_len >= 3 then
-- Oracle中的DECODE是拿第一个数依次和之后的偶数位值进行比较,相同则取偶数位+1的数值
for i in 2..(v_len - 1) loop
v_ret := null;
if mod(i, 2) = 0 then
if p_decode_list[1] = p_decode_list[i] then
v_ret := p_decode_list[i+1];
elsif p_decode_list[1] <> p_decode_list[i] then
if v_len = i + 2 and v_len > 3 then
v_ret := p_decode_list[v_len];
end if;
end if;
end if;
exit when v_ret is not null;
end loop;
else
raise exception 'UPG-00938: not enough args for function.';
end if;
return v_ret;
end;
$$
language plpgsql;
 
-----------------------------------------------------------数字decode函数--------------------------------------------------------
 
create or replace function decode(variadic p_decode_list numeric[])
returns numeric
 as
$$
declare
 -- 获取数组长度(即入参个数)
 v_len integer := array_length(p_decode_list, 1);
 -- 声明存放返回值的变量
 v_ret numeric;
begin
 /*
 * 功能说明:模拟Oracle中的DECODE功能(字符串处理, 其它格式可以自行转换返回值)
 * 参数说明:格式同Oracle相同,至少三个参数
 * 实现原理: 1、VARIADIC 允许变参; 2、Oracle中的DECODE是拿第一个数依次和之后的偶数位值进行比较,相同则取偶数位+1的数值,否则取最后一位值(最后一位为偶数为,否则为null)
 */
  
 -- 同Oracle相同当参数不足三个抛出异常
 if v_len >= 3 then
  -- Oracle中的DECODE是拿第一个数依次和之后的偶数位值进行比较,相同则取偶数位+1的数值
  for i in 2..(v_len - 1) loop
   v_ret := null;
   if mod(i, 2) = 0 then
    if p_decode_list[1] = p_decode_list[i] then
     v_ret := p_decode_list[i+1];
    elsif p_decode_list[1] <> p_decode_list[i] then
     if v_len = i + 2 and v_len > 3 then
      v_ret := p_decode_list[v_len];
     end if;
    end if;
   end if;
   exit when v_ret is not null;
  end loop;
 else
  raise exception 'UPG-00938: not enough args for function.';
 end if;
 return v_ret;
end;
$$
 language plpgsql;
 
---------------------------------------------------------
create or replace function decode(variadic p_decode_list character[])
returns character
 as
$$
declare
 -- 获取数组长度(即入参个数)
 v_len integer := array_length(p_decode_list, 1);
 -- 声明存放返回值的变量
 v_ret character;
begin
 /*
 * 功能说明:模拟Oracle中的DECODE功能(字符串处理, 其它格式可以自行转换返回值)
 * 参数说明:格式同Oracle相同,至少三个参数
 * 实现原理: 1、VARIADIC 允许变参; 2、Oracle中的DECODE是拿第一个数依次和之后的偶数位值进行比较,相同则取偶数位+1的数值,否则取最后一位值(最后一位为偶数为,否则为null)
 */
  
 -- 同Oracle相同当参数不足三个抛出异常
 if v_len >= 3 then
  -- Oracle中的DECODE是拿第一个数依次和之后的偶数位值进行比较,相同则取偶数位+1的数值
  for i in 2..(v_len - 1) loop
   v_ret := null;
   if mod(i, 2) = 0 then
    if p_decode_list[1] = p_decode_list[i] then
     v_ret := p_decode_list[i+1];
    elsif p_decode_list[1] <> p_decode_list[i] then
     if v_len = i + 2 and v_len > 3 then
      v_ret := p_decode_list[v_len];
     end if;
    end if;
   end if;
   exit when v_ret is not null;
  end loop;
 else
  raise exception 'UPG-00938: not enough args for function.';
 end if;
 return v_ret;
end;
$$
 language plpgsql;
1.1.3. oracle dual表pg实现
CREATE OR REPLACE VIEW dual AS
SELECT NULL::"unknown"
WHERE 1 = 1;
-- 开放给用户
ALTER TABLE dual OWNER TO himc;
GRANT ALL ON TABLE dual TO himc;
GRANT SELECT ON TABLE dual TO public;
1.1.4. oracle-merge into的pg实现
--/***
--*pg实现
--* 实例:插入模型表一条数据,如果id存在,则版本号加1,并且更新更新时间。
--*其中 EXCLUDED.{字段}代表插入字段值,即now()
--*
--*/
INSERT INTO himc_model ( modelid, modelname, status, CREATEUSER, VERSION, createtime, updatetime, modifyuser )
VALUES
    ( 'himc_1678696981571', '新建模型2023-03-28 16:08:23', '0',         'admin1', 1, now( ), now( ), 'admin1' )
     
    ON CONFLICT(modelid)
    DO
    UPDATE SET version = (SELECT version FROM himc_model WHERE modelid = 'himc_1678696981571') + 1, updatetime = EXCLUDED.updatetime  RETURNING *;
 
 
 
 
--/***
--*对应的oracle实现
--* 实例:插入模型表一条数据,如果id存在,则版本号加1,并且更新更新时间。
--*/
MERGE INTO himc_model A USING ( SELECT 'himc_1678696981571' AS modelId FROM dual ) b ON ( A.modelId = b.modelId )
WHEN NOT MATCHED THEN
    INSERT ( modelid, modelname, status, CREATEUSER, VERSION, createtime, updatetime, modifyuser )
VALUES
    ( 'himc_1678696981571', '新建模型2023-03-28 16:08:23', '0',         'admin1', 0, sysdate, sysdate, 'admin1' )
WHEN MATCHED THEN
UPDATE
    SET A.VERSION = A.VERSION + 1
    SET A.UPDATETIME = SYSDATE
WHERE
    A.modelId = 'himc_1678696981571'
    AND A.VERSION >= 1


1.2. 程序切换-mybatis方言集成
1.2.1. DatabaseIdProvider 与SqlSessionFactory 注入
/**
 * 自动识别使用的数据库类型 在mapper.xml中databaseId的值就是跟这里对应, 如果没有databaseId选择则说明该sql适用所有数据库
 */
@Bean
public DatabaseIdProvider getDatabaseIdProvider() {
    DatabaseIdProvider databaseIdProvider = new VendorDatabaseIdProvider();
    Properties properties = new Properties();
    properties.setProperty("Oracle", "oracle");
    properties.setProperty("MySQL", "mysql");
    properties.setProperty("DB2", "db2");
    properties.setProperty("Derby", "derby");
    properties.setProperty("H2", "h2");
    properties.setProperty("HSQL", "hsql");
    properties.setProperty("MS-SQL", "ms-sql");
    properties.setProperty("PostgreSQL", "postgresql");
    databaseIdProvider.setProperties(properties);
    return databaseIdProvider;
}
 
@Bean(name = "sessionFactory")
@Primary
public SqlSessionFactory sessionFactory() throws Exception {
    MybatisSqlSessionFactoryBean sqlSessionFactoryBean = new MybatisSqlSessionFactoryBean();
    sqlSessionFactoryBean.setDatabaseIdProvider(getDatabaseIdProvider());
    sqlSessionFactoryBean.setDataSource(dataSource());
    sqlSessionFactoryBean.setTypeAliasesPackage(typeAliasesPackage);
    PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
    sqlSessionFactoryBean.setMapperLocations(resolver.getResources("classpath*:sql-mapper/**/*.xml"));
 
    sqlSessionFactoryBean.setTypeEnumsPackage("com.hisense.hiatmp.himc.**.enums");
    return sqlSessionFactoryBean.getObject();
}
1.2.2. mapper改造(兼容的不需要改造,不添加databaseId即所有的数据源共用)
<insert id="insertProcess" databaseId="oracle">
    insert into himc_model_process(processId, modelId, processName, calcId, calcParam, calcMapping,
    processOrder,logic, type, computetype)
    values( #{processId,jdbcType=VARCHAR},
    #{modelId,jdbcType=VARCHAR},
    #{processName,jdbcType=NVARCHAR},
    #{calcId,jdbcType=VARCHAR},
    #{calcParam,jdbcType=VARCHAR},
    #{calcMapping,jdbcType=NVARCHAR},
    #{processOrder,jdbcType=CHAR},
    #{logic,jdbcType=CLOB},
    #{type,jdbcType=CHAR},
    #{computeType,jdbcType=CHAR})
</insert>
<insert id="insertProcess" databaseId="postgresql">
    insert into himc_model_process(processId, modelId, processName, calcId, calcParam, calcMapping,
    processOrder,logic, type, computetype)
    values( #{processId,jdbcType=VARCHAR},
    #{modelId,jdbcType=VARCHAR},
    #{processName,jdbcType=VARCHAR},
    #{calcId,jdbcType=VARCHAR},
    #{calcParam,jdbcType=VARCHAR},
    #{calcMapping,jdbcType=VARCHAR},
    #{processOrder,jdbcType=CHAR},
    #{logic,jdbcType=CLOB},
    #{type,jdbcType=CHAR},
    #{computeType,jdbcType=CHAR})
</insert>

上一篇:大数据工具(一)parquet文件生成与上传

下一篇:大数据权限认证Kerberos

推荐阅读
鲁ICP备2022041402号  |   QQ:8346417  |  地址:山东青岛