
简介这是若依开源框架全面适配达梦数据库的完整源码包面向正在使用若依构建企业应用、又需要切换到国产化数据库环境的技术团队可绕开数据库驱动、方言和事务兼容等集成过程中的常见障碍。整个压缩包共635个文件、体积约4.66MB文件类型覆盖面较广253个Java源码构成后端业务逻辑124个HTML配合83个JS与42个CSS完善前端交互另有XML/YML配置、SQL脚本、VM模板、PNG/GIF图标、bat/sh启动脚本与JAR驱动包可支撑代码阅读、二次开发直至环境部署。内容除完整工程外还包含达梦库表结构设计说明与典型SQL适配示例并用PDM建模文件辅助理解表关系帮助读者快速定位连接池、事务管理与分页查询等需要调整的位置。已有3032人学习下载适合具备一定若依基础、希望引入达梦数据库的开发者作为落地参考资料。1. 项目概述为什么若依要适配达梦数据库做国产化项目这行当久了你会碰上一个绕不开的组合若依框架加达梦数据库。若依RuoYi在国内开发圈的分量不用多说基于Spring Boot加MyBatis的快速开发平台前后端分离版本、微服务版本都在大量生产项目里跑着。而达梦数据库DM8作为国产数据库里出货量第一梯队的选手在政务、军工、金融这些强调信创的行业里几乎是标配。这两者适配的核心矛盾在于若依框架从诞生那天起就是为MySQL服务的无论是默认的SQL语法、分页插件、代码生成器的模板还是定时任务里默认调用的存储函数全都写着MySQL的烙印。你直接把若依的SQL脚本丢给达梦执行大概率会在建表语句的注释语法、字段类型映射、自增主键定义这几个地方卡住接着在联调阶段陆续踩中分页SQL方言不兼容、函数不存在、排序规则不一致这些暗坑。因此把若依完整迁移到达梦数据库不只是一份SQL脚本改一改那么简单而是要从建表、持久层SQL、配置文件、ORM方言、定时任务兼容、代码生成器这六个维度做一次系统性适配。这篇文章基于我实际做完的一个若依前后端分离版本集成达梦8的完整项目把源码层面的改造思路、关键配置、踩坑记录全部整理出来。适合两类读者一类是正在做信创适配、被甲方要求数据库必须换成达梦的Java开发另一类是打算在国产技术栈上从零搭建项目的团队。照着这篇文章的思路走一遍你手头的若依项目大概率一天之内就能在达梦上跑起来。2. 整体设计思路与适配方案选型2.1 明确适配边界改哪些、不改哪些在做任何技术适配之前最忌讳的就是一上来就闷头改代码。我在拿到这个任务时先花了一个下午把若依源码里跟数据库相关的部分全部扫了一遍用依赖梳理的方式把改造边界摸清楚。若依框架和数据库交互的链路从配置文件到SQL执行一共涉及五层pom.xml依赖管理、application-druid.yml数据源配置、MyBatis Mapper接口与XML文件、代码生成器模板、定时任务脚本Quartz的表结构和调用函数。在这些层里有一部分是必须改的比如建表SQL、数据源驱动配置、个别SQL方言还有一部分是不需要大动的比如业务模块里90%以上的CRUD操作因为MyBatis在底层已经帮你把大部分参数绑定和结果集映射做掉了。这里说个重要的选型判断。完备的适配方案有两种姿态一种是只做能跑起来级别的最小改动把MySQL的SQL脚本手工翻译到达梦语法改完配置就交差另一种是做物尽其用级别的深度适配还想办法把达梦的Oracle兼容模式、行列存储引擎这些高级特性用起来。如果项目只是验收性质的信创适配前者就够了。但如果你打算在达梦上长期稳定运行我的建议是直接按后者来因为前者的埋坑风险会在后续的功能迭代、报表统计、数据迁移中反复爆雷。我这次做的改造最终落在了一个折中方案上核心框架全面适配业务代码最小侵入。2.2 达梦数据库与MySQL的核心差异聊适配之前有必要把达梦数据库跟MySQL之间的几个关键差异讲透。搞懂了这些差异你就明白后面每一步改造为什么要那么写了。第一点是SQL方言体系。达梦数据库虽然也兼容MySQL协议但它的底层更接近Oracle的语法逻辑。默认安装的达梦8兼容模式一般建议选MySQL这样LIMIT分页、反引号字段名这些写法还能用。但问题是如果达梦装在Oracle模式下或者有些生产库为了兼容老系统切换到Oracle模式那若依自带的MySQL风格分页SQL就全废了。我这次测试环境用的是MySQL兼容模式属于最省心的状况但即便如此还是有不少MySQL专属函数在达梦里找不到对应实现。第二点是字段类型映射。若依的建表SQL是MySQL风格varchar、datetime、longtext、int(11)这类写法在达梦里都有对应类型但细节匹配有讲究。举个例子MySQL的datetime和达梦的datetime都可以用但达梦更推荐timestampMySQL的tinyint(1)表示布尔值达梦里实际上会映射成smallint还是tinyint得看兼容参数配置。更麻烦的是text、longtext这类大字段类型达梦里对应的是TEXT和CLOB如果你在改造时配错了插入超长字符串会直接报错。第三点是自增主键和序列。MySQL的AUTO_INCREMENT在达梦里同样支持但达梦更原生的是SEQUENCE序列 触发器的方式。若依的多数表用的都是自增主键所以建表SQL里AUTO_INCREMENT要保留但如果你用的是达梦Oracle模式就必须改用序列加触发器。第四点是函数和运算符差异。这是最容易踩坑的地方。MySQL里的IFNULL、DATE_FORMAT、GROUP_CONCAT、CURDATE这些函数在达梦里要么不支持、要么函数名不一样。达梦有NVL、TO_CHAR这类Oracle风味的函数。这意味着若依Mapper XML里的若干SQL片段需要手工改写。2.3 适配方案的总体架构整个适配工作我在计划阶段拆成了四个阶段分别是准备、改造、联调、验证。准备阶段要做的事情是搭环境、初始化达梦实例、导入原文的MySQL脚本先跑一遍看看报什么错把错误清单作为改造的输入。改造阶段关注代码和SQL脚本按依赖层逐个击破。联调阶段是启动若依前后端项目走一遍登录、菜单、权限、增删改查、代码生成的完整链路。验证阶段重点压一下并发、大批量数据导入和定时任务执行确认不会在运行几天后突然出幺蛾子。每个阶段的产出物都是下一阶段的输入比如准备阶段的错误清单直接决定改造阶段的优先级联调阶段的报错日志又补充到排查手册里。这个流程走下来整个适配过程是可控的而不是走一步看一步。3. 核心源码改造实操从建表到Java代码逐层适配3.1 环境准备与达梦数据库初始化要点在动手改代码之前先把环境准备好。达梦8的安装包从官网申请试用版就行Windows和Linux都有对应的安装包。我这里用的是Linux服务器部署安装步骤不复杂重点是初始化实例时的几个参数选择。初始化实例时有一个数据库兼容模式的选项下拉菜单里有MySQL、Oracle、SQL Server等选项这里务必选MySQL兼容模式。如果你已经装好了才发现模式不对也不是完全没法补救但后续会遇到一堆莫名其妙的SQL兼容问题强烈建议重装。安装完成后用达梦自带的manager管理工具创建一个业务数据库这个库对应若依里的ry-vue这个schema。紧接着做一件关键的事情把若依项目里的sql/ry_2024xxxx.sqlMySQL版本找出来先用达梦的迁移工具或者手工方式执行一遍。你会看到第一批报错信息大致包括注释语法不支持、字段类型不识别、索引名重复这几类。这些报错信息很有价值建议截图存档因为后面每一步改造其实就是在消灭这些报错。补充一个很实用的建议达梦8安装完了之后默认会开一个叫做模式的概念Oracle风格的模式对应MySQL的数据库schema。而若依项目里的数据源URL写的是jdbc:dm://localhost:5236默认连的是达梦的SYSDBA模式。如果你不希望业务表都建在SYSDBA模式里最好在manager工具里新建一个模式建表和授权都放在这个新模式下后面JDBC URL里也可以指定schema。3.2 数据源配置改造Druid连接池与驱动若依的数据源配置集中在resources/application-druid.yml这个文件里。MySQL版本下的默认配置driverClassName是com.mysql.cj.jdbc.Driverurl是jdbc:mysql://localhost:3306/ry-vue。要切换到达梦这两行配置需要改掉# application-druid.yml 关键片段 spring: datasource: druid: driverClassName: dm.jdbc.driver.DmDriver url: jdbc:dm://localhost:5236?schemaRUOYI username: SYSDBA password: ******这里有两处细节特别容易出错。第一达梦的JDBC驱动包不在Maven中央仓库里需要从达梦安装目录的drivers/jdbc目录里找到DmJdbcDriver18.jar对应JDK8及以上用mvn install:install-file命令手动安装到本地仓库然后才能在pom.xml里正常依赖。命令参考如下mvn install:install-file -DfileDmJdbcDriver18.jar -DgroupIdcom.dameng -DartifactIdDmJdbcDriver18 -Dversion8.1.2.192 -Dpackagingjar然后在若依的父pom或ruoyi-framework模块pom里加入这个依赖坐标。注意不要盲目改成spring-boot-starter-jdbc自带的驱动加载方式因为若依的Druid配置里还有很多监控相关的参数沿用druid-spring-boot-starter最稳妥。第二MySQL兼容模式下Druid的wall防火墙过滤器有可能会拦掉一些达梦特有的SQL写法。如果启动时报错提示sql injection violation可以在Druid配置里把wall的配置放宽spring: datasource: druid: filter: wall: enabled: true config: multiStatementAllow: true noneBaseStatementAllow: true不过这里我不建议把wall完全关掉做信创项目时安全合规审计往往会查这个开关。用multiStatementAllow就够了。3.3 建表SQL脚本的达梦方言重写这是整个改造中工作量最大的部分。若依原生的MySQL建表脚本分成两部分框架核心表sys_user、sys_role、sys_menu这些和业务示例表。框架核心表是必须手动改写的因为后续若依的登录、权限模块全都依赖这些表的结构任何字段类型错误都会在联调时暴露出来。我在实际操作中采用了一边建一边跑的方式先用达梦manager工具手动把框架核心表建好然后在若依的后端配置里把数据源切过去挨个启动模块看报错。这个过程有点笨但排查效率最高。下面把最常见的几类建表差异整理出来第一类是注释写法不同。MySQL里字段注释和表注释都写在字段定义后面用COMMENT xxx而达梦MySQL兼容模式也支持这种写法但如果你遇到个别版本报错可以把COMMENT单独放在建表语句之后-- MySQL风格达梦MySQL兼容模式通常可用 CREATE TABLE sys_user ( user_id int NOT NULL AUTO_INCREMENT COMMENT 用户ID, user_name varchar(30) NOT NULL COMMENT 用户账号, PRIMARY KEY (user_id) ) COMMENT 用户信息表; -- 达梦兼容写法 CREATE TABLE sys_user ( user_id INT IDENTITY(1,1) NOT NULL, user_name VARCHAR(30) NOT NULL, PRIMARY KEY (user_id) ); COMMENT ON TABLE sys_user IS 用户信息表; COMMENT ON COLUMN sys_user.user_id IS 用户ID;IDENTITY是达梦的自增语法。如果你在MySQL兼容模式下使用AUTO_INCREMENT也能通过但Oracle模式下只能用IDENTITY或序列。为了适配面更广我最后把核心表统一改成了IDENTITY写法。第二类是字段类型映射。若依里大量的datetime、longtext、int(11)类型建议在达梦里全部显式改成timestamp、text、int。特别是longtext这个类型在达梦里不存在直接改成CLOB或者TEXT如果用的是TEXT类型要注意它的长度上限达梦的TEXT对应MySQL的MEDIUMTEXT级别一般够用。第三类是索引名和约束名的全局唯一问题。若依原生脚本里索引名比较随意比如idx_name、idx_order等在MySQL里同一个库下可以重复但在达梦里索引名的唯一性要求更严格。建议在改写时给索引统一加表名前缀。3.4 Mapper XML中的SQL方言适配若依的核心Mapper XML文件里虽然大多数是简单的CRUD操作但有几个文件里藏着MySQL专属语法。根据我实际的代码检索结果需要重点排查的有三个文件。第一个是SysUserMapper.xml里面有个selectUserList的查询方法用了大量的条件拼接其中有IFNULL函数。达梦在MySQL兼容模式下提供了IFNULL的别名实现所以这个偶尔能跑过。但保险起见还是改成NVL达梦对NVL的支持更原生。第二个是SysMenuMapper.xml它的菜单权限SQL里用到了DATE_FORMAT函数来格式化和排序菜单时间。如果只是格式展示可以在Java层用SimpleDateFormat处理SQL里直接去掉函数。我在改造时选择了后者减少SQL层面的方言依赖。第三个是通用分页查询。若依默认使用PageHelper做物理分页PageHelper的dialect配置需要切换成达梦方言。在application.yml里的PageHelper配置段设置helperDialect为dmpagehelper: helperDialect: dm reasonable: true supportMethodsArguments: true params: countcountSql如果不配置这个PageHelper会根据URL自动识别数据库类型有些版本识别不了达梦会退回MySQL方言生成的COUNT查询和分页SQL都用LIMIT语句达梦在MySQL兼容模式下看着能跑但实际的物理分页采用的是达梦的LIMIT实现性能上可能会有偏差。手动指定dm方言之后PageHelper会用达梦特有的分页语法生成SQL跑起来更稳。再补一个容易忽略的坑若依的代码生成器模块ruoyi-generator里有从数据库读取表结构生成代码的逻辑它查询表元数据的SQL也是MySQL风格读取information_schema.COLUMNS遇到达梦时这里需要单独改造。具体来说在GenTableMapper.xml和GenTableColumnMapper.xml里有两段查询表结构和列信息的SQL需要改成查询达梦的系统视图常见写法是SELECT COLUMN_NAME, DATA_TYPE, COLUMN_COMMENT FROM ALL_TAB_COLUMNS WHERE TABLE_NAME #{tableName}这里要说明一下ALL_TAB_COLUMNS在达梦中是存在的Oracle兼容的系统视图。若依代码生成器改造完之后你才能在页面上继续用导入表功能。不常写代码生成器的同事可能注意不到这里但真正用来一导报表单就报错查半天都在查XML语法纯粹浪费时间。3.5 Quartz定时任务与达梦的兼容处理若依自带了一套基于Quartz的定时任务模块对应的quartz.sql脚本里有十几张Quartz框架表。这套脚本在达梦里运行完会有几处报错集中在BLOB、CLOB类型的默认值以及索引长度超限上。我的处理经验是不要在达梦里手动建这十几张表而是直接在Quartz的持久化配置里把quartz的jobStore切换成达梦友好配置。具体做法是若依的application.yml里有一段spring.quartz的配置默认情况下若依把Quartz的jobStore设置成了JDBCJobStore同时使用数据库表存储任务。在达梦环境下你需要确认Quartz的驱动代理类可以正常工作。通常遇到的是如下报错org.quartz.impl.jdbcjobstore.LockException: Failure obtaining db row lock: 达梦数据库锁表现异常这个报错的原因多半是Quartz的默认锁机制select ... for update在达梦上锁表失败解决办法是把quartz.properties里配置两个关键参数org.quartz.jobStore.driverDelegateClassorg.quartz.impl.jdbcjobstore.StdJDBCDelegate org.quartz.jobStore.isClusteredfalse org.quartz.jobStore.tablePrefixQRTZ_如果你不需要集群部署isClustered设为false能避免大部分锁问题。如果一定要集群模式那需要仔细检查QRTZ_LOCKS表的存在性和表结构保证select for update能正常执行。4. 集成过程中高频问题与排查实战记录4.1 驱动加载失败或ClassNotFoundException这是一个出现频率极高的问题。报错内容通常是dm.jdbc.driver.DmDriver这个类找不到。排查步骤三步走第一步检查pom依赖是否已经引入DmJdbcDriver18第二步检查Maven本地仓库里是否有这个jar用mvn dependency:tree查看第三步确认打包方式。如果你是把若依打成可执行jar部署要确认DmJdbcDriver18的jar确实打进去了可以在解压后的BOOT-INF/lib目录里找到它。出现这个问题的根本原因基本都出在手动安装jar这一步。普通JDBC驱动jar如果有pom文件的话还好达梦的驱动jar在安装目录里没有pommvn install时你需要手工指定groupI、artifactId、version。如果指定的坐标跟pom.xml里写的不一致启动时类加载自然失败。4.2 中文乱码与字符集设置达梦数据库的字符集默认跟安装时操作系统环境有关如果安装时选了GBK而你项目里用UTF-8查询出的中文就会乱码。解决办法是在达梦manager工具里新建数据库时把字符集明确设置为UTF-8。已建好的库可以通过修改实例参数调整但不建议在生产环境这么干风险较大。另外JDBC URL上有必要加上字符集参数。达梦的驱动会读取连接串里的encoding或characterEncoding参数例如url: jdbc:dm://localhost:5236?schemaRUOYIcharacterEncodingutf-84.3 分组查询时出现不是GROUP BY表达式错误这个问题在从MySQL迁到达梦时几乎必现。原因是MySQL的sql_mode默认允许select列不在group by中出现而达梦更严格要求select列表里的非聚合列都必须出现在group by子句中。若依的菜单表、岗位表里多少有几个这类统计SQL遇到之后老老实实改写SQL把非聚合列加进group by或者改成子查询方式。举个例子SysMenuMapper.xml里有一个查询菜单列表并关联用户表的SQL它会select出多张表的字段group by却只写了菜单表主键。原样跑MySQL没问题到达梦就报错。改法是查出业务字段后group by全部字段列表或者把统计字段用min/max包裹。我把这类问题整理成一个高频速查表问题现象根因解决方案ClassNotFoundException: DmDriver驱动jar未正确引入手工mvn install并核对坐标建表时COMMENT语法报错达梦模式对注释写法要求严改用COMMENT ON TABLE/COLUMN语法分页SQL用了LIMIT报错PageHelper方言识别异常手动指定helperDialectdmselect中出现非聚合列且未group by达梦对分组查询校验严格改写SQL补齐group by字段定时任务报锁表异常Quartz集群锁在达梦上的兼容问题关闭集群模式或维护QRTZ_LOCKS表插入大文本报字段超长MySQL的longtext被映射为CLOB长度限制变化改TEXT类型或者调整达梦参数代码生成器导入表列表为空默认查询information_schema不兼容改造GenTableMapper查询系统视图4.4 若依微服务版本与Flowable工作流适配如果你的项目用的是若依微服务版本改动逻辑类似但文件更分散每个微服务模块都有自己的数据源配置和SQL脚本。你需要在gateway、system、auth等各个服务里重复做数据源切换。另外如果集成了Flowable工作流引擎Flowable 6.7.2对达梦的适配有官方补丁它是通过flowable-dm-dialect之类的方言包实现的在你的pom里单独引入flowable的达梦方言依赖后把ProcessEngineConfigurationConfigurer里的databaseType设置为dm即可。Nacos如果也要使用达梦作为存储官方提供的MySQL存储脚本不能直接用达梦社区有适配脚本。不过Nacos的默认存储目前还是内置Derby或MySQL达梦适配需要动Nacos源码一般建议维持Nacos用MySQL核心业务数据用达梦这样集成成本可控。5. 实操心得与后续扩展建议最后聊几点我在这个项目里踩出来的实在心得。第一点如果你是要交付给甲方的信创适配项目不要只提供改好的源码还要整理一份MySQL到达梦数据库改造对照说明把每个文件的改动点、改动原因、验证结果都列出来。这份文档在验收评审时能省掉大量解释成本也方便后来人快速接手。第二点代码生成器这层改造很容易被忽略但不改的话后期甲方会拿它来快速生成业务CRUD一用就报错体验极差。所以无论项目时间多紧这层一定要动。第三点测试阶段建议专门留一天做回归SQL对比。用同样一批数据在MySQL和达梦上分别跑一遍若依的全部功能把两边的查询结果做diff你会发现有些SQL虽然两边都不报错但结果集的排序或字段默认值不一样。这类隐蔽问题不在联调阶段抓出来上线后就会变成数据不准的投诉。再补充一个后续扩展的方向达梦8自身支持Oracle模式和MySQL模式的双模切换你可以研究一下让同一个若依系统在这两种模式下都能运行。思路是在MyBatis层封装一套针对不同数据库方言的StatementProvider或者直接在XML里用databaseId标签指定不同数据库的SQL。若依目前的代码没有利用MyBatis的databaseId机制但这块儿改动不大值得做。这样一来你的项目就真正做到了数据库无关未来无论遇到什么信创数据库要求都能快速响应。本文还有配套的精品资源点击获取