若依(RuoYi)多数据源深度实战从配置到代码生成的完整解决方案在当今企业级应用开发中多数据源支持已成为标配需求。若依(RuoYi)作为国内流行的快速开发框架其多数据源功能设计巧妙但配置过程常让开发者踩坑。本文将带你从零开始不仅解决基础配置问题更深入探讨如何在不同数据源间无缝生成代码并针对常见报错提供根治方案。1. 多数据源架构设计与核心配置若依的多数据源实现基于Spring BootDruidMyBatis组合其核心在于动态数据源路由机制。理解这一设计理念才能避免后续开发中的各种玄学问题。1.1 数据源配置的黄金法则在application-druid.yml中配置多数据源时必须遵循以下规范spring: datasource: druid: master: url: jdbc:mysql://localhost:3306/ry_main?useSSLfalse username: root password: 123456 slave_orderdb: # 关键点1名称全小写不要用驼峰或下划线 enabled: true # 关键点2必须显式启用 url: jdbc:mysql://localhost:3306/order_db?useSSLfalse username: order_user password: order123常见配置错误对照表错误配置示例正确写法错误原因slaveOrderDBslaveorderdb驼峰命名导致注入失败slave_order_dbslaveorderdb下划线会被特殊处理未设置enabledenabled: true数据源不会初始化1.2 枚举类与动态数据源绑定在DataSourceType.java中定义枚举时需保持与配置的严格对应public enum DataSourceType { MASTER, // 主库 SLAVE_ORDERDB, // 对应slaveorderdb配置 SLAVE_PRODUCTDB // 对应slaveproductdb配置 }注意枚举名称中的下划线会被自动转换为配置中的小写形式这是Spring Boot的命名策略决定的。2. 代码生成器的多数据源适配若依的代码生成器默认只扫描主库表结构要使其支持多数据源需要解决两个关键问题数据源切换和元数据表同步。2.1 控制器级别的数据源切换在GenController上添加DataSource注解是最佳实践DataSource(DataSourceType.SLAVE_ORDERDB) RestController RequestMapping(/tool/gen) public class GenController extends BaseController { // 该控制器所有方法都将使用SLAVE_ORDERDB数据源 }切换策略对比注解位置作用范围适用场景类级别整个控制器该数据源专属代码生成方法级别单个方法混合数据源操作无注解使用主库默认情况2.2 元数据表的跨库同步每个需要生成代码的从库都必须包含以下两个表结构gen_table- 存储表基本信息gen_table_column- 存储字段信息快速建表SQLMySQL示例-- 在目标库中执行 CREATE TABLE gen_table ( table_id bigint(20) NOT NULL AUTO_INCREMENT, table_name varchar(200) DEFAULT , table_comment varchar(500) DEFAULT , class_name varchar(100) DEFAULT , tpl_category varchar(200) DEFAULT crud, package_name varchar(100) DEFAULT , module_name varchar(30) DEFAULT , business_name varchar(30) DEFAULT , function_name varchar(50) DEFAULT , function_author varchar(50) DEFAULT , options varchar(1000) DEFAULT , create_by varchar(64) DEFAULT , create_time datetime DEFAULT NULL, update_by varchar(64) DEFAULT , update_time datetime DEFAULT NULL, remark varchar(500) DEFAULT NULL, PRIMARY KEY (table_id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4; -- gen_table_column结构类似需完整复制3. 高频报错分析与解决方案3.1 Table doesnt exist系列错误错误场景### Error querying database. Cause: java.sql.SQLSyntaxErrorException: Table order_db.gen_table doesnt exist解决步骤确认目标库中是否存在gen_table和gen_table_column检查表结构是否完整特别是字段类型和长度验证数据库用户是否有读写权限3.2 数据源切换失效问题典型表现注解已添加但依然访问主库切换时出现连接池耗尽排查清单检查enabled配置是否为true确认Druid连接池参数合理特别是maxActive查看启动日志是否有数据源初始化报错// 调试技巧在DruidConfig中添加日志输出 Bean Primary public DynamicDataSource dataSource(DataSource masterDataSource) { logger.info(Initializing data sources: {}, targetDataSources.keySet()); return new DynamicDataSource(masterDataSource, targetDataSources); }4. 高级应用多数据源代码生成策略4.1 分模块代码生成对于大型项目建议按业务域划分数据源和代码结构com. ├── order │ ├── config # 订单数据源配置 │ ├── entity # 订单实体 │ └── mapper # 订单Mapper └── product ├── config # 产品数据源配置 ├── entity # 产品实体 └── mapper # 产品Mapper生成配置示例# 订单模块配置 packageNamecom.order moduleNameorder businessNameorder # 产品模块配置 packageNamecom.product moduleNameproduct businessNameproduct4.2 多数据源事务处理在跨数据源操作时需要特别注意事务边界// 错误示例跨数据源事务不生效 Transactional public void processOrder() { orderDao.insert(order); // SLAVE_ORDERDB inventoryDao.update(stock); // SLAVE_PRODUCTDB } // 正确做法使用分布式事务或最终一致性方案 DataSource(DataSourceType.SLAVE_ORDERDB) public void createOrder() { orderDao.insert(order); sendInventoryUpdateEvent(order); }实际项目中遇到过一个典型案例在电商系统中订单数据和库存数据分属不同数据库最初尝试用本地事务管理跨库操作导致数据不一致。后来改用消息队列实现最终一致性系统稳定性显著提升。
若依(RuoYi)多数据源实战:手把手教你生成不同库的代码(附常见报错解决方案)
若依(RuoYi)多数据源深度实战从配置到代码生成的完整解决方案在当今企业级应用开发中多数据源支持已成为标配需求。若依(RuoYi)作为国内流行的快速开发框架其多数据源功能设计巧妙但配置过程常让开发者踩坑。本文将带你从零开始不仅解决基础配置问题更深入探讨如何在不同数据源间无缝生成代码并针对常见报错提供根治方案。1. 多数据源架构设计与核心配置若依的多数据源实现基于Spring BootDruidMyBatis组合其核心在于动态数据源路由机制。理解这一设计理念才能避免后续开发中的各种玄学问题。1.1 数据源配置的黄金法则在application-druid.yml中配置多数据源时必须遵循以下规范spring: datasource: druid: master: url: jdbc:mysql://localhost:3306/ry_main?useSSLfalse username: root password: 123456 slave_orderdb: # 关键点1名称全小写不要用驼峰或下划线 enabled: true # 关键点2必须显式启用 url: jdbc:mysql://localhost:3306/order_db?useSSLfalse username: order_user password: order123常见配置错误对照表错误配置示例正确写法错误原因slaveOrderDBslaveorderdb驼峰命名导致注入失败slave_order_dbslaveorderdb下划线会被特殊处理未设置enabledenabled: true数据源不会初始化1.2 枚举类与动态数据源绑定在DataSourceType.java中定义枚举时需保持与配置的严格对应public enum DataSourceType { MASTER, // 主库 SLAVE_ORDERDB, // 对应slaveorderdb配置 SLAVE_PRODUCTDB // 对应slaveproductdb配置 }注意枚举名称中的下划线会被自动转换为配置中的小写形式这是Spring Boot的命名策略决定的。2. 代码生成器的多数据源适配若依的代码生成器默认只扫描主库表结构要使其支持多数据源需要解决两个关键问题数据源切换和元数据表同步。2.1 控制器级别的数据源切换在GenController上添加DataSource注解是最佳实践DataSource(DataSourceType.SLAVE_ORDERDB) RestController RequestMapping(/tool/gen) public class GenController extends BaseController { // 该控制器所有方法都将使用SLAVE_ORDERDB数据源 }切换策略对比注解位置作用范围适用场景类级别整个控制器该数据源专属代码生成方法级别单个方法混合数据源操作无注解使用主库默认情况2.2 元数据表的跨库同步每个需要生成代码的从库都必须包含以下两个表结构gen_table- 存储表基本信息gen_table_column- 存储字段信息快速建表SQLMySQL示例-- 在目标库中执行 CREATE TABLE gen_table ( table_id bigint(20) NOT NULL AUTO_INCREMENT, table_name varchar(200) DEFAULT , table_comment varchar(500) DEFAULT , class_name varchar(100) DEFAULT , tpl_category varchar(200) DEFAULT crud, package_name varchar(100) DEFAULT , module_name varchar(30) DEFAULT , business_name varchar(30) DEFAULT , function_name varchar(50) DEFAULT , function_author varchar(50) DEFAULT , options varchar(1000) DEFAULT , create_by varchar(64) DEFAULT , create_time datetime DEFAULT NULL, update_by varchar(64) DEFAULT , update_time datetime DEFAULT NULL, remark varchar(500) DEFAULT NULL, PRIMARY KEY (table_id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4; -- gen_table_column结构类似需完整复制3. 高频报错分析与解决方案3.1 Table doesnt exist系列错误错误场景### Error querying database. Cause: java.sql.SQLSyntaxErrorException: Table order_db.gen_table doesnt exist解决步骤确认目标库中是否存在gen_table和gen_table_column检查表结构是否完整特别是字段类型和长度验证数据库用户是否有读写权限3.2 数据源切换失效问题典型表现注解已添加但依然访问主库切换时出现连接池耗尽排查清单检查enabled配置是否为true确认Druid连接池参数合理特别是maxActive查看启动日志是否有数据源初始化报错// 调试技巧在DruidConfig中添加日志输出 Bean Primary public DynamicDataSource dataSource(DataSource masterDataSource) { logger.info(Initializing data sources: {}, targetDataSources.keySet()); return new DynamicDataSource(masterDataSource, targetDataSources); }4. 高级应用多数据源代码生成策略4.1 分模块代码生成对于大型项目建议按业务域划分数据源和代码结构com. ├── order │ ├── config # 订单数据源配置 │ ├── entity # 订单实体 │ └── mapper # 订单Mapper └── product ├── config # 产品数据源配置 ├── entity # 产品实体 └── mapper # 产品Mapper生成配置示例# 订单模块配置 packageNamecom.order moduleNameorder businessNameorder # 产品模块配置 packageNamecom.product moduleNameproduct businessNameproduct4.2 多数据源事务处理在跨数据源操作时需要特别注意事务边界// 错误示例跨数据源事务不生效 Transactional public void processOrder() { orderDao.insert(order); // SLAVE_ORDERDB inventoryDao.update(stock); // SLAVE_PRODUCTDB } // 正确做法使用分布式事务或最终一致性方案 DataSource(DataSourceType.SLAVE_ORDERDB) public void createOrder() { orderDao.insert(order); sendInventoryUpdateEvent(order); }实际项目中遇到过一个典型案例在电商系统中订单数据和库存数据分属不同数据库最初尝试用本地事务管理跨库操作导致数据不一致。后来改用消息队列实现最终一致性系统稳定性显著提升。