1. 多数据源配置的背景与价值
在传统企业级应用开发中,单一数据源架构往往难以满足复杂业务场景的需求。特别是在国产化替代浪潮下,许多项目需要同时兼容传统MySQL数据库和国产达梦DM数据库。这种混合架构既能保证现有业务平稳运行,又能满足政策合规要求。
我在最近参与的某政务云项目中就遇到了这样的需求:核心业务模块需要继续使用MySQL保证稳定性,而新开发的统计分析模块则要求使用国产达梦DM数据库。通过若依微服务框架的多数据源支持,我们成功实现了两种数据库的无缝集成。下面分享具体实现方案和踩坑经验。
2. 环境准备与基础配置
2.1 组件版本选择
- 若依微服务版:建议使用3.7.0及以上版本
- MySQL:5.7或8.0版本(注意8.0需要调整驱动配置)
- 达梦DM:DM8版本
- JDK:1.8或11(达梦对高版本JDK支持较好)
特别注意:达梦数据库驱动需要从官网获取,Maven中央仓库可能没有最新版本。建议手动下载后安装到本地仓库。
2.2 数据库驱动配置
在父pom.xml中添加依赖管理:
<dependencyManagement> <dependencies> <!-- MySQL驱动 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.28</version> </dependency> <!-- 达梦驱动 --> <dependency> <groupId>dm</groupId> <artifactId>DmJdbcDriver</artifactId> <version>8.1.1.193</version> </dependency> </dependencies> </dependencyManagement>3. 多数据源核心配置实现
3.1 数据源配置类编写
创建两个独立的配置类分别管理MySQL和达梦数据源:
@Configuration @MapperScan(basePackages = "com.ruoyi.mysql.mapper", sqlSessionTemplateRef = "mysqlSqlSessionTemplate") public class MysqlDataSourceConfig { @Bean(name = "mysqlDataSource") @ConfigurationProperties(prefix = "spring.datasource.mysql") public DataSource mysqlDataSource() { return DataSourceBuilder.create().build(); } @Bean(name = "mysqlSqlSessionFactory") public SqlSessionFactory mysqlSqlSessionFactory( @Qualifier("mysqlDataSource") DataSource dataSource) throws Exception { SqlSessionFactoryBean bean = new SqlSessionFactoryBean(); bean.setDataSource(dataSource); bean.setMapperLocations(new PathMatchingResourcePatternResolver() .getResources("classpath:mapper/mysql/*.xml")); return bean.getObject(); } // 其他必要bean配置... } // 达梦配置类结构类似,注意修改包路径和bean名称3.2 application.yml配置
spring: datasource: mysql: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/ry-cloud?useSSL=false username: root password: 123456 dm: driver-class-name: dm.jdbc.driver.DmDriver url: jdbc:dm://localhost:5236/ry-dm username: SYSDBA password: SYSDBA4. 达梦数据库特殊处理
4.1 SQL语法适配
达梦与MySQL在SQL语法上存在差异,需要特别注意:
分页查询:
- MySQL:
LIMIT 0, 10 - 达梦:
OFFSET 0 ROWS FETCH NEXT 10 ROWS ONLY
- MySQL:
日期函数:
- MySQL:
NOW() - 达梦:
CURRENT_TIMESTAMP
- MySQL:
4.2 事务管理配置
在启动类上添加事务管理器:
@EnableTransactionManagement @SpringBootApplication public class RuoYiApplication { public static void main(String[] args) { SpringApplication.run(RuoYiApplication.class, args); } @Bean(name = "mysqlTransactionManager") public PlatformTransactionManager mysqlTransactionManager( @Qualifier("mysqlDataSource") DataSource dataSource) { return new DataSourceTransactionManager(dataSource); } @Bean(name = "dmTransactionManager") public PlatformTransactionManager dmTransactionManager( @Qualifier("dmDataSource") DataSource dataSource) { return new DataSourceTransactionManager(dataSource); } }5. 动态数据源切换实战
5.1 自定义注解实现
创建数据源切换注解:
@Target({ElementType.METHOD, ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface DataSource { String value() default "mysql"; }5.2 AOP切面实现
@Aspect @Component @Order(1) public class DataSourceAspect { @Before("@annotation(dataSource)") public void beforeSwitchDataSource(DataSource dataSource) { String dsId = dataSource.value(); if (!DynamicDataSourceContextHolder.containsDataSource(dsId)) { throw new RuntimeException("数据源"+dsId+"不存在"); } DynamicDataSourceContextHolder.setDataSourceType(dsId); } @After("@annotation(dataSource)") public void afterSwitchDataSource(DataSource dataSource) { DynamicDataSourceContextHolder.clearDataSourceType(); } }6. 常见问题排查指南
6.1 连接池配置问题
| 症状 | 可能原因 | 解决方案 |
|---|---|---|
| 连接泄漏 | 未正确关闭连接 | 配置removeAbandonedTimeout |
| 性能低下 | 连接数不足 | 调整maxActive参数 |
| 达梦连接失败 | 驱动版本不匹配 | 使用达梦官方推荐驱动 |
6.2 事务管理问题
跨数据源事务需要引入分布式事务解决方案,如Seata。在若依框架中建议:
- 避免在单个方法中同时操作多个数据源
- 对于必须跨库的操作,使用最终一致性方案
- 达梦事务隔离级别默认是READ COMMITTED,与MySQL有差异
7. 性能优化建议
连接池调优:
- MySQL:建议使用HikariCP
spring: datasource: mysql: type: com.zaxxer.hikari.HikariDataSource hikari: maximum-pool-size: 20 minimum-idle: 5达梦特有参数:
-- 调整达梦内存参数 ALTER SYSTEM SET 'MEMORY_TARGET' = '2G' SCOPE=SPFILE;MyBatis缓存配置:
<settings> <setting name="cacheEnabled" value="true"/> <setting name="localCacheScope" value="STATEMENT"/> </settings>
在实际项目中,我们通过这套方案成功支持了日均10万+的混合查询请求。达梦数据库在统计分析类查询中表现优异,而MySQL则保证了核心业务的高并发写入稳定性。