若依框架兼容mysql和kingbase数据库
一、我是在 ruoyi-common-datasource 模块里,创建了一个 DatabaseIdConfig:

使用 MyBatis 自带的 VendorDatabaseIdProvider:把 数据库产品名 映射为 MyBatis 的 databaseId:MySQL → mysql,KingbaseES / PostgreSQL → kingbase(金仓基于 PG,所以两个都映射为 kingbase)Spring Boot 自动配置 MyBatis 时,会自动使用这个 DatabaseIdProvider。为了防止有些场景没正确设置 databaseId,又实现了一个 ApplicationListener<ApplicationReadyEvent>:应用启动完成后,遍历所有 SqlSessionFactory:如果 Configuration.getDatabaseId() 为空,就用 DatabaseIdProvider.getDatabaseId(dataSource) 手动算一遍并 setDatabaseId。日志里会输出每个 SqlSessionFactory 识别到的 databaseId,方便排查。
效果:
无论是 MySQL 还是金仓,只要 JDBC 能连上,MyBatis 都能统一得到 _databaseId = 'mysql' 或 _databaseId = 'kingbase',供 XML 里判断。
二、Mapper 层根据 _databaseId 写双分支 SQL
在 Mapper.xml 里,使用了 MyBatis 的 _databaseId 变量配合 <choose>/<when> 来做方言兼容。
主要几类差异:
1. 时间函数 / 日期计算差异
例如工单统计里“上周、本周”的时间区间:
- MySQL 分支用 DATE_SUB、CURDATE()、WEEKDAY():
<when test="_databaseId == 'mysql'">
AND DATE(wp.appear_time) >= DATE_SUB(CURDATE(), INTERVAL WEEKDAY(CURDATE()) + 7 DAY)
AND DATE(wp.appear_time) <= DATE_SUB(CURDATE(), INTERVAL WEEKDAY(CURDATE()) + 1 DAY)
</when>
- 金仓分支用 DATE_TRUNC('week', CURRENT_DATE) + INTERVAL:
<otherwise>
AND DATE(wp.appear_time) >= (DATE_TRUNC('week', CURRENT_DATE) + INTERVAL '1 day') - INTERVAL '7 days'
AND DATE(wp.appear_time) <= (DATE_TRUNC('week', CURRENT_DATE) + INTERVAL '1 day') - INTERVAL '1 day'
</otherwise>
2. 布尔 / TINYINT 存储差异
- MySQL 下直接插入/更新 #{menuCheckStrictly}(Boolean 自动映射成 tinyint)。
- 金仓下先用 CASE WHEN ... THEN 1 ELSE 0 END,再 CAST 成 SMALLINT:
<choose>
<when test="_databaseId == 'kingbase'">
CAST(CASE WHEN #{menuCheckStrictly} THEN 1 ELSE 0 END AS SMALLINT),
</when>
<otherwise>
#{menuCheckStrictly},
</otherwise>
</choose>
3. 日期时间函数差异(sysdate() vs CURRENT_TIMESTAMP)
创建时间、更新时间等字段:
- MySQL 用 sysdate()。
- 金仓用 CURRENT_TIMESTAMP:
4. 关键字/字段名差异
比如 from 等在 MySQL 里需要反引号,在金仓里可以直接用或用双引号,这些也通过 _databaseId == 'mysql' 做了分支处理。
三、使用方式:怎么切库而不改代码
基于这一整套设计,切换数据库只需要:
- 在配置中心(如 ruoyi-system-dev.yml )里改:
- driver-class-name(MySQL 或 Kingbase 驱动)
- url(jdbc:mysql://... 或 jdbc:kingbase8://... / PG 协议)
- 用户名、密码
- 代码层 完全不需要改:
- DatabaseIdProvider 会自动识别成 mysql 或 kingbase。
- Mapper XML 自动走对应 <when test="_databaseId == 'xxx'"> 分支。
总结
现有 MySQL 项目只要按照此方式增加 Mapper 中的 kingbase 分支和一个公共 DatabaseIdConfig,就能做到“一套代码,双数据库”。
更多推荐


所有评论(0)