Skip to content

国产化适配:MySQL项目适配兼容达梦数据库操作

约 1787 字大约 6 分钟

国产化数据库达梦

2025-03-11

将现有的Spring Boot + Mybatis + MySQL项目迁移到国产数据库如达梦数据库。本文档详细介绍了如何调整现有项目以兼容达梦数据库,并提供了迁移过程中遇到的一些常见问题及其解决方案。

项目兼容达梦数据库适配方案与常见问题解决方案

数据库函数替换策略

1. GROUP_CONCAT() 函数处理

MySQL中的GROUP_CONCAT()用于合并分组内的值为一个字符串。在达梦数据库中,可以使用WM_CONCAT()函数来实现类似的功能。

实现步骤:

  • 在达梦数据库中,使用WM_CONCAT()函数代替MySQL的GROUP_CONCAT()
SELECT WM_CONCAT(your_field) AS concatenated_fields FROM your_table GROUP BY your_grouping_field;

需要注意的是,尽管WM_CONCAT()可以在一定程度上替代GROUP_CONCAT(),但两者之间存在一些差异。例如,WM_CONCAT()可能不支持某些高级选项(如排序、分隔符自定义等),这时需要根据具体情况决定是否继续使用SQL层面的聚合还是转到Java代码层进行处理。

Java代码层处理示例: 如果WM_CONCAT()不能满足需求,可以在Service层使用Java流(Stream)API或传统的循环结构来聚合数据。

List<String> concatenatedResult = yourEntityList.stream()
    .map(YourEntity::getField)
    .collect(Collectors.joining(","));

2. 时间计算函数的替换

针对MySQL中的DATE_SUB(NOW(), INTERVAL 28 DAY)DATE_ADD(),推荐在Java代码中计算好时间之后,再通过参数传递给MyBatis Mapper。

实现示例:

LocalDateTime now = LocalDateTime.now();
LocalDateTime dateBefore28Days = now.minusDays(28);
yourMapper.selectByDate(dateBefore28Days);

通过这种方式,可以更精确地控制时间计算逻辑,并且便于测试和维护。

3. 聚合函数转换

将MySQL中的count(name = '张三' or null)转换为MySQL和达梦数据库都支持的SUM(CASE WHEN name = '张三' THEN 1 ELSE 0 END)格式。

SQL语句调整:

SELECT SUM(CASE WHEN name = '张三' THEN 1 ELSE 0 END) AS count_field FROM your_table;

这种做法不仅提高了SQL的可移植性,也增强了查询表达式的清晰度。

4. DATE_FORMAT()函数

以 date_format 函数为例,MySQL 中的 date_format 函数可以在 DM 数据库 中使用 to_char 或 to_date 函数改写,改写后在达梦中可以达到相同的效果,

示例 如下:

-- MySQL 
select date_format(sysdate(), '%Y 年%m ') from dual 
-- DM
select translate(to_char(sysdate, 'yyyy-mm#'),'-#','年月') from dua
-- MySQL 
select DATE_ FORMAT(C_ FIRST_TIME,'%Y-%m-%d %H') FROM DUAL; 
-- DM
select TO_CHAR(C_FIRST_TIME, 'YYYY- MM- DD HH24') FROM DUAL;

也可以在达梦数据库里自定义创建一个date_format函数,然后函数里面的处理逻辑用达梦的to_char、to_date,这样的好处是不需要去调整代码里的sql语句。

5. CAST()函数

DM 中的 cast()函数的用法虽然和 MySQL 一致,但使用效果存在不同, MySQL 中对于数值类型的 value 转 char 类型没有限制,DM 中则存在限制,会 报“数据转换失败”等报错,可将 cast(数值类型的 valueaschar)转换为 cast(数值 类型的valueasvarchar),对于unsigned类型可以根据实际情况做对应改变或确定是 否有必要进行转换。

SQL语法及规范注意事项

GROUP BY 子句遵循标准

确保在GROUP BY子句中包含所有非聚合字段。这符合SQL标准,并有助于提高查询的正确性和性能。

实践建议:

  • 审查所有涉及GROUP BY的查询,确保其符合SQL标准。

  • 使用ORM框架提供的功能自动处理这些细节,减少手动编写复杂SQL的风险。

例如:

select name, type, sum(grades) as grades_sum
from student
group by name

这种sql就不行,不符合数据库的常规规范,select里的非聚合字段时name、type,而 group by 里只有一个name字段,这就不兼容mysql8、人大金仓和达梦数据库等。

需要调整为

select name, type, sum(grades) as grades_sum
from student
group by name, type

其他优化点和注意事项

  • 数据类型映射:仔细检查实体类与数据库表之间的数据类型映射,特别是对于日期时间类型、布尔类型等可能存在的差异。
  • 索引优化:迁移时重新评估并优化索引设置,以适应新数据库的特点。

使用mybatis的sql标签配置databaseId

当出现实在无法做到一个sql兼容多个数据库,且无法使用 java 代码的情况,可以使用myabtis提供的sql标签加databaseId配置。

数据库databaseId配置
mysql数据库不用配置,默认为mysql
人大金仓数据库kingbase
达梦数据库dm

例如:

    <sql id="DATE_ADD_SQL">
       DATE_ADD(MAX(statistical_date), INTERVAL 1 DAY)
    </sql>
    
    <sql id="DATE_ADD_SQL" databaseId="kingbase">
        (MAX(statistical_date) + INTERVAL '1 DAY')
    </sql>
    
    <sql id="DATE_ADD_SQL" databaseId="dm">
        DATEADD(DAY, 1, MAX(statistical_date))
    </sql>
    
	<select id="get" resultType="com.business.statistical.table.entity.StatisticalTable">
        SELECT unit_id,
        (CASE WHEN MAX(statistical_date) IS NOT NULL THEN <include refid="DATE_ADD_SQL" /> ELSE MAX(statistical_date) END) statisticalDate
        FROM statistical_table
        WHERE unit_id in
        <foreach collection="ids" item="id" separator="," open="(" close=")">
            #{id}
        </foreach>
        GROUP BY unit_id
    </select>

将数据库从mysql迁移到达梦数据库方案

1. 客户端组件安装

先在本地安装好达梦数据库提供的客户端工具组件

工具下载地址:https://www.dameng.com/list_103.html

安装好之后可以看到如下几个工具

image-20250311142028756

名称说明
DM管理工具相当于dbeaver,是达梦数据库专用的可视化工具。
DM数据迁移工具用于将其他数据库的库迁移到达梦数据库,或将达梦数据库的库迁移到其他数据库。
DM控制台工具没用过
DM审计分析工具没用过
DM性能监视工具没用过

2. 初次迁库操作步骤

初次将mysql数据库的库迁移到达梦数据库的操作步骤如下:

新建连接

打开 DM管理工具 ,新建连接

image-20250311144110942

使用运维人员提供的达梦数据库超管账号登录

image-20250311145135049

创建表空间

登录之后创建表空间

image-20250311145600728

创建管理用户

image-20250311145710359

image-20250311145918816

系统权限选这些

image-20250311150053799

创建模式

模式不需要手动创建,创建好用户之后,就会自动创建一个该用户的模式。

image-20250311150650269

DM管理工具的操作暂时结束,接下来切换到DM数据迁移工具

新建迁移任务

打开 DM数据迁移工具 ,新建迁移任务

image-20250311143454354

image-20250311143537459

选择从mysql迁移到达梦数据库。

image-20250311143609899

输入要迁移的mysql数据库基础信息,然后再下一步。

image-20250311151029131

输入达梦的数据库基础信息

image-20250311151118992

选择迁移策略

建议将出错后继续执行取消掉,当出现错误的时候建议清理已经迁移的库和表数据,解决错误信息后,重新执行迁移任务。

image-20250311151204532

image-20250311151457281

image-20250311151709988

开始迁移

image-20250311151950131

成功执行后,迁移工作结束!