SpringBoot多数据源配置:MySQL与SQL Server整合实践
1. 项目概述
在企业级应用开发中,多数据源连接是常见需求。SpringBoot作为Java生态中最流行的框架之一,其简化配置的特性让多数据源管理变得更加高效。本文将详细介绍如何在SpringBoot项目中同时连接MySQL和SQL Server数据库,并使用MyBatisPlus进行数据操作测试。
2. 环境准备与依赖配置
2.1 基础环境要求
开发多数据源项目前,需要确保本地环境满足以下条件:
- JDK 1.8或更高版本
- Maven 3.6+
- IntelliJ IDEA或Eclipse开发工具
- MySQL 5.7+/SQL Server 2012+数据库服务
2.2 核心依赖引入
在pom.xml中添加必要依赖:
<dependencies> <!-- SpringBoot基础依赖 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- MyBatisPlus依赖 --> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.5.3.1</version> </dependency> <!-- 数据库驱动 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>com.microsoft.sqlserver</groupId> <artifactId>mssql-jdbc</artifactId> <version>9.4.1.jre8</version> <scope>runtime</scope> </dependency> <!-- 连接池 --> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>1.2.8</version> </dependency> </dependencies>注意:SQL Server驱动版本需要与数据库版本匹配,否则可能出现兼容性问题
3. 多数据源配置实现
3.1 配置文件设置
在application.yml中配置双数据源:
spring: datasource: druid: # 主数据源 (MySQL) primary: url: jdbc:mysql://localhost:3306/db_primary?useSSL=false&serverTimezone=UTC 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;databaseName=db_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 BaseMapper<PrimaryUser> { } // SQL Server Mapper @Repository public interface SecondaryProductMapper extends BaseMapper<SecondaryProduct> { }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 List<PrimaryUser> getUsers() { return primaryUserMapper.selectList(null); } public List<SecondaryProduct> 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); // 查询验证 List<PrimaryUser> users = dataService.getUsers(); List<SecondaryProduct> 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 ThreadLocal<String> 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-underline=true
7. 生产环境建议
- 敏感配置加密:使用jasypt加密数据源密码
- 多环境配置:通过profile区分开发/测试/生产环境
- 监控集成:配置Druid监控界面
- 连接泄漏检测:开启removeAbandoned相关配置
- 慢SQL监控:配置filter.stat.log-slow-sql=true
实际项目中,多数据源配置需要根据具体业务需求进行调整。对于读写分离场景,可以考虑使用ShardingSphere等专业中间件。在微服务架构下,更推荐将不同数据源拆分为独立服务,通过API调用实现数据交互。