文章目录
- 简介
- 安装下载
- 连接配置
- pom文件
- application.yml配置
- 代码适配
- 注意事项
- 1、创建表结构语法
- 2、索引名唯一问题
- 3、新增字段
- 4、切换模式名
- 5、工具客户端更新数据
- 6、group by语法
- 7、加解密函数替换
- 8、删除符号`
- 9、separator分隔替换成LISTAGG函数
- 10、函数now()替换成SYSDATE()
- 11、函数GROUP_CONCAT替换成wm_concat
- 12、函数STR_TO_DATE替换成TO_DATE
- 13、函数替换 CURDATE()
- 14、函数ANY_VALUE()替换成FIRST_VALUE
- 15、函数REGEXP()替换成REGEXP_LIKE
- 16、函数 if 替换成COALESCE
简介
现有一个已经以mysql作为数据源的项目,由于需要适配一套信创环境,这里将达梦数据库选作关系型数据库,本文主要介绍如何从mysql适配到达梦。达梦官网地址
安装下载
安装包地址 https://eco.dameng.com/download/
连接配置
这里使用阿里的数据库链接池druid以及达梦提供的数据驱动包进行数据库连接
pom文件
<dependency>
<groupId>com.dameng</groupId>
<artifactId>dm-jdbc</artifactId>
<version>1.8</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.2.20</version>
</dependency>
application.yml配置
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
druid:
driver-class-name: dm.jdbc.driver.DmDriver
url: jdbc:dm://127.0.0.1:35236/SBOM1?serverTimezone=Asia/Shanghai
username: TECENT_VIDEO
password: 12345678901QWER
initial-size: 10
max-active: 100
min-idle: 10
max-wait: 60000
pool-prepared-statements: true
max-pool-prepared-statement-per-connection-size: 20
time-between-eviction-runs-millis: 60000
min-evictable-idle-time-millis: 300000
validation-query: SELECT 1 FROM DUAL
test-while-idle: true
test-on-borrow: false
test-on-return: false
filter:
stat:
log-slow-sql: true
slow-sql-millis: 1000
merge-sql: false
wall:
config:
multi-statement-allow: true
代码适配
这里以mybatis为例,重新复制一份mapper文件到新目录,配置文件直接将sql方法的实现指向该新目录,接着将xml里面的sql按照达梦的语法方式适配,大多数情况是不需要改写的。
改写的方法可以参照本文注意事项中提到的事项点
注意事项
mysql适配达梦数据库时,有许多语法和函数需要我们去留意适配,本章内容总结了一些主要的问题处理方案,基本可以满足大家的适配需求,若有更多的问题,可以到达梦社区搜索->达梦社区
1、创建表结构语法
创建表的时候,不支持在列的后面直接加comment注释,使用 COMMENT ON IS
代替,如下:
CREATE TABLE role_biz_t
(
account_id BIGINT NOT NULL,
role_id BIGINT NOT NULL,
PRIMARY KEY (account_id, role_id) -- 在达梦数据库中,不需要指定USING BTREE,因为B树索引是默认的
)STORAGE(INITIAL 64, NEXT 64);
COMMENT ON TABLE role_biz_t IS '前台用户角色关系表' ;
2、索引名唯一问题
mysql中我们对索引的唯一性限制在某张表,但是达梦索引名字的唯一性是限制范围是整个模式,所以创建索引的时候最好加上表名来保证唯一性
CREATE INDEX idx_aa_code_create_user ON aa_code(create_user) ;
CREATE UNIQUE INDEX idx_sca_lib_uk_license_id ON sca_lib("license_id") ;
3、新增字段
新增字段和创建表的时候,不支持在列的后面直接加comment注释,同样使用使用 COMMENT ON IS
代替,如下:
ALTER TABLE test_item_t ADD service_name varchar(100) DEFAULT NULL;
COMMENT ON COLUMN test_item_t.service_name IS '服务名称';
4、切换模式名
在mysql中我们常常用USE database_name;
来完成切换数据库,但是实际上达梦切换模式的语法不是这个。
解决方案:
-- TECENT_VIDEO是模式名 表示切换到该模式下,类似与mysql的切换库
SET SCHEMA TECENT_VIDEO;
5、工具客户端更新数据
在一些常见的工具客户端执行插入或更新数据时,记得在末尾加上commit;
否则你会发现表中数据并没更新。
UPDATE sca_lib SET grade_a=-1 WHERE grade_name='未知';
commit;
6、group by语法
mysql group by后面可以填写查询后的结果别名,但是达梦必须得跟上原本的字段名
解决方案:
SELECT t1.developer as mydeveloper,t1.id as myid
FROM test t1
group by t1.developer,t1.id
7、加解密函数替换
若原本mysql 用的是AES_DECRYPT(UNHEX(phone),密钥) ,则需要替换成达梦特有的加解密函数,如下
-- 插入一条数据
INSERT INTO TASK (cust_id,cust_name,sex)
VALUES(12225,
BINTOCHAR (
UTL_ENCODE.BASE64_ENCODE (
DBMS_CRYPTO.ENCRYPT(
UTL_I18N.STRING_TO_RAW ( '李四', 'UTF8' ),
DBMS_CRYPTO.ENCRYPT_AES128 + DBMS_CRYPTO.CHAIN_ECB + DBMS_CRYPTO.PAD_PKCS5,
UTL_I18N.STRING_TO_RAW ( '2112122121212121222', 'UTF8' )
)
)
)
,1);
-- 模糊查询
select * from TASK t where
UTL_I18N.RAW_TO_CHAR (
DBMS_CRYPTO.DECRYPT (
UTL_ENCODE.BASE64_DECODE (
CHARTOBIN ( cust_name)),
DBMS_CRYPTO.ENCRYPT_AES128 + DBMS_CRYPTO.CHAIN_ECB + DBMS_CRYPTO.PAD_PKCS5,
UTL_I18N.STRING_TO_RAW ( '2112122121212121222', 'UTF8' )
),
'UTF8'
)
like '%李四%' ;
8、删除符号`
达梦sql不支持符号` 需要去掉,否则会报语法有误,处理的范围包括实体类、代码中的sql拼接以及xml文件
解决方案:
SELECT developer id FROM test
-- 或者
SELECT developer id FROM "test"
9、separator分隔替换成LISTAGG函数
解决方案:
select LISTAGG(field_name , ',') as fieldName from sys_dict_detail_t
10、函数now()替换成SYSDATE()
now()函数在达梦不存在,需要替换成SYSDATE()
INSERT INTO sys_job (create_time, update_time) VALUES( sysdate(), sysdate());
11、函数GROUP_CONCAT替换成wm_concat
解决方案:
SELECT wm_concat(app.id) as scaIds FROM task app
12、函数STR_TO_DATE替换成TO_DATE
解决方案:
SELECT * FROM task t
where (t.start_time between TRUNC(TO_DATE('2024-07-28', 'YYYY-MM-DD HH24:MI:SS'))
and TRUNC(TO_DATE('2024-08-28', 'YYYY-MM-DD HH24:MI:SS')) + 1)
13、函数替换 CURDATE()
解决方案:
DATE_FORMAT(create_time,'%Y-%m-%d') >= CURDATE() - INTERVAL 1 DAY
替换成
DATE_FORMAT(create_time,'%Y-%m-%d') >= DATE_FORMAT(SYSDATE - 1, 'YYYY-MM-DD')
14、函数ANY_VALUE()替换成FIRST_VALUE
解决方案:
select FIRST_VALUE(id) as aid from sca_app_component_license
group by license_str
15、函数REGEXP()替换成REGEXP_LIKE
解决方案:
select * from task_fun_item_t where REGEXP_LIKE(code_url, '^[0-9]+$');
16、函数 if 替换成COALESCE
解决方案:
SELECT
t1.developer,
COALESCE(t1.first_vul_json == null, t1.last_vul_json, t1.first_vul_json) AS vul_json
FROM task_vul_repair_statistic_t t1