适配国产数据库 - 人大金仓(KingBase8)
1.JPA 适配
总结一些,JPA 工程 适配 人大金仓(KingBase) 数据库遇到的些问题
1.0.背景
项目需要适配国产化,其中包含操作系统、数据库、消息中间件等
当前 为 SpringBoot + JPA 工程 适配 KingBase8
1.1.SQL 转化
KingBase8 安装后,会自带 迁移工具的
KingBase 迁移工具通过 这个工具 可以转换 MySQL 或 Oracle 的脚本(DDL,DML)
1.2.问题
1.2.1 qrtz 注册失败
异常堆栈工程里使用了qrtz ,qrtz 需要DB保存一些调度任务的详情,但在注册这些数据的时候,告诉说表字段太短了(Oracle、MySQL 里长度都是1)
排查好久也没跟踪到具体失败的原因是什么,后来将 表字段大小调大了点,临时处理了。
1.2.2 org.hibernate.engine.jdbc.spi.SqlExceptionHelper [129] -| 错误: 关系 "hibernate_sequence" 不存在
异常堆栈解决:
在 DB 里创建了这个序列
create sequence HIBERNATE_SEQUENCE
minvalue 100
maxvalue 9223372036854775807
start with 1
increment by 1
cache 10;
minvalue 为什么是100?
有些表有初始化数据,占据了自动生成的 id 值
2 JDBC 适配
2.0.背景
老旧的 spring 工程, 使用原生的 jdbc 进行数据的操作
2.1.问题
2.1.1 com.kingbase8.util.KSQLException: The query "select TTEXT from TABLE where ID=?" is not locked.
异常堆栈问题产生的原因在于 要 更新 clob 类型的字段导致的
解决: 在 select 语句后加上 for update ,把行锁住,再来更新
官方给的示例:
官方示例
抛异常代码块
MySQL 与 Oracle 不需要 for update 来锁行的操作
3 其他问题
3.1 需注意的表字段类型
smallserial/serial/bigserial : 自动增长的数据类型,可用作主键
varchar : 有单位 byte / char. 缺省是byte
执行ddl之前:需显示指定 char
set char_default_type = 'char';
3.2 触发器
与Oracle对比
Oracel:
CREATE
OR REPLACE TRIGGER IS_TEST_TRG BEFORE INSERT ON IS_TEST FOR EACH ROW
WHEN (NEW.ID IS NULL)
BEGIN
SELECT
IS_TEST.NEXTVAL INTO : NEW.ID
FROM
DUAL;
END;
KingBase8
CREATE
OR REPLACE TRIGGER IS_TEST_TRG BEFORE INSERT ON
PUBLIC.IS_TEST FOR EACH ROW
WHEN(
(
NEW.ID IS NULL
)
) AS BEGIN SELECT
IS_TEST .NEXTVAL INTO NEW.ID
FROM
DUAL;
END;
区别:
1.在BEGIN 前加 AS
2.INTO 后,NEW.ID 前的 : 删掉
3.3 使用 druid 数据源
在启动的时候报不支持的db类型
java.lang.IllegalStateException: dbType not support : null, url jdbc:kingbase8://192.168.2.1:54321/test
druid 不支持 kb8 的 防御sql 注入而报错在跟踪源码后发现,druid 并不支持 kingbase8 ,并且又在官方 FAQ 里找到相关解释
FAQ去掉了 wall 后工程正常启动