公司动态

SpringBoot多数据源配置:MySQL与SQL Server整合实践

📅 2026/8/11 4:04:22
SpringBoot多数据源配置:MySQL与SQL Server整合实践
1. 项目概述在企业级应用开发中多数据源连接是常见需求。SpringBoot作为Java生态中最流行的框架之一其简化配置的特性让多数据源管理变得更加高效。本文将详细介绍如何在SpringBoot项目中同时连接MySQL和SQL Server数据库并使用MyBatisPlus进行数据操作测试。2. 环境准备与依赖配置2.1 基础环境要求开发多数据源项目前需要确保本地环境满足以下条件JDK 1.8或更高版本Maven 3.6IntelliJ IDEA或Eclipse开发工具MySQL 5.7/SQL Server 2012数据库服务2.2 核心依赖引入在pom.xml中添加必要依赖dependencies !-- SpringBoot基础依赖 -- dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-web/artifactId /dependency !-- MyBatisPlus依赖 -- dependency groupIdcom.baomidou/groupId artifactIdmybatis-plus-boot-starter/artifactId version3.5.3.1/version /dependency !-- 数据库驱动 -- dependency groupIdmysql/groupId artifactIdmysql-connector-java/artifactId scoperuntime/scope /dependency dependency groupIdcom.microsoft.sqlserver/groupId artifactIdmssql-jdbc/artifactId version9.4.1.jre8/version scoperuntime/scope /dependency !-- 连接池 -- dependency groupIdcom.alibaba/groupId artifactIddruid-spring-boot-starter/artifactId version1.2.8/version /dependency /dependencies注意SQL Server驱动版本需要与数据库版本匹配否则可能出现兼容性问题3. 多数据源配置实现3.1 配置文件设置在application.yml中配置双数据源spring: datasource: druid: # 主数据源 (MySQL) primary: url: jdbc:mysql://localhost:3306/db_primary?useSSLfalseserverTimezoneUTC username: root password: 123456 driver-class-name: com.mysql.cj.jdbc.Driver initial-size: 5 max-active: 20 min-idle: 5 # 从数据源 (SQL Server) secondary: url: jdbc:sqlserver://localhost:1433;databaseNamedb_secondary username: sa password: your_password driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver initial-size: 5 max-active: 153.2 数据源配置类创建数据源配置类实现多数据源隔离Configuration MapperScan(basePackages com.example.mapper.primary, sqlSessionTemplateRef primarySqlSessionTemplate) public class PrimaryDataSourceConfig { Bean(name primaryDataSource) ConfigurationProperties(prefix spring.datasource.druid.primary) Primary public DataSource primaryDataSource() { return DruidDataSourceBuilder.create().build(); } Bean(name primarySqlSessionFactory) Primary public SqlSessionFactory primarySqlSessionFactory(Qualifier(primaryDataSource) DataSource dataSource) throws Exception { MybatisSqlSessionFactoryBean bean new MybatisSqlSessionFactoryBean(); bean.setDataSource(dataSource); bean.setMapperLocations(new PathMatchingResourcePatternResolver() .getResources(classpath:mapper/primary/*.xml)); return bean.getObject(); } Bean(name primaryTransactionManager) Primary public DataSourceTransactionManager primaryTransactionManager(Qualifier(primaryDataSource) DataSource dataSource) { return new DataSourceTransactionManager(dataSource); } Bean(name primarySqlSessionTemplate) Primary public SqlSessionTemplate primarySqlSessionTemplate(Qualifier(primarySqlSessionFactory) SqlSessionFactory sqlSessionFactory) { return new SqlSessionTemplate(sqlSessionFactory); } }从数据源配置类类似主要区别在于使用Qualifier指定数据源移除Primary注解修改包路径和Bean名称4. MyBatisPlus集成与测试4.1 实体类与Mapper定义为两个数据源分别创建实体和Mapper// MySQL实体 Data TableName(t_user) public class PrimaryUser { TableId(type IdType.AUTO) private Long id; private String username; private Integer age; } // SQL Server实体 Data TableName(t_product) public class SecondaryProduct { TableId(type IdType.AUTO) private Long id; private String name; private BigDecimal price; }Mapper接口需要放在对应的包路径下// MySQL Mapper Repository public interface PrimaryUserMapper extends BaseMapperPrimaryUser { } // SQL Server Mapper Repository public interface SecondaryProductMapper extends BaseMapperSecondaryProduct { }4.2 服务层实现创建服务类操作双数据源Service public class DataService { Autowired private PrimaryUserMapper primaryUserMapper; Autowired private SecondaryProductMapper secondaryProductMapper; Transactional(transactionManager primaryTransactionManager) public void addUser(PrimaryUser user) { primaryUserMapper.insert(user); } Transactional(transactionManager secondaryTransactionManager) public void addProduct(SecondaryProduct product) { secondaryProductMapper.insert(product); } public ListPrimaryUser getUsers() { return primaryUserMapper.selectList(null); } public ListSecondaryProduct getProducts() { return secondaryProductMapper.selectList(null); } }4.3 测试验证编写测试类验证多数据源SpringBootTest class MultiDataSourceTest { Autowired private DataService dataService; Test void testMultiDataSource() { // 测试MySQL数据源 PrimaryUser user new PrimaryUser(); user.setUsername(testUser); user.setAge(25); dataService.addUser(user); // 测试SQL Server数据源 SecondaryProduct product new SecondaryProduct(); product.setName(测试产品); product.setPrice(new BigDecimal(99.99)); dataService.addProduct(product); // 查询验证 ListPrimaryUser users dataService.getUsers(); ListSecondaryProduct products dataService.getProducts(); Assert.notEmpty(users, MySQL数据源测试失败); Assert.notEmpty(products, SQL Server数据源测试失败); } }5. 高级配置与优化5.1 动态数据源切换对于更复杂的场景可以实现动态数据源路由public class DynamicDataSource extends AbstractRoutingDataSource { Override protected Object determineCurrentLookupKey() { return DataSourceContextHolder.getDataSourceType(); } } public class DataSourceContextHolder { private static final ThreadLocalString contextHolder new ThreadLocal(); public static void setDataSourceType(String dataSourceType) { contextHolder.set(dataSourceType); } public static String getDataSourceType() { return contextHolder.get(); } public static void clearDataSourceType() { contextHolder.remove(); } }5.2 事务管理优化多数据源环境下事务管理需要特别注意使用Transactional注解时明确指定transactionManager避免跨数据源事务分布式事务考虑使用Seata等方案事务传播行为需要根据业务场景谨慎选择5.3 性能调优建议连接池配置优化根据并发量调整max-active设置合理的validation-query配置remove-abandoned-timeout防止连接泄漏MyBatisPlus二级缓存配置批量操作使用executeBatch提升性能6. 常见问题排查6.1 连接失败问题问题现象SQL Server连接报错08001解决方案检查SQL Server是否启用TCP/IP协议验证SQL Server身份验证模式混合模式检查防火墙设置是否放行1433端口6.2 事务不生效问题问题现象跨数据源操作时事务不回滚原因分析默认事务管理器只能管理单个数据源解决方案使用JTA实现分布式事务拆分为多个独立事务最终一致性方案补偿6.3 MyBatisPlus映射问题问题现象SQL Server表字段映射失败解决方案检查TableName注解是否正确SQL Server字段建议使用下划线命名配置mybatis-plus.global-config.db-config.column-underlinetrue7. 生产环境建议敏感配置加密使用jasypt加密数据源密码多环境配置通过profile区分开发/测试/生产环境监控集成配置Druid监控界面连接泄漏检测开启removeAbandoned相关配置慢SQL监控配置filter.stat.log-slow-sqltrue实际项目中多数据源配置需要根据具体业务需求进行调整。对于读写分离场景可以考虑使用ShardingSphere等专业中间件。在微服务架构下更推荐将不同数据源拆分为独立服务通过API调用实现数据交互。