ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

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

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: 15

3.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 事务管理优化

多数据源环境下事务管理需要特别注意:

  1. 使用@Transactional注解时明确指定transactionManager
  2. 避免跨数据源事务(分布式事务考虑使用Seata等方案)
  3. 事务传播行为需要根据业务场景谨慎选择

5.3 性能调优建议

  1. 连接池配置优化:

    • 根据并发量调整max-active
    • 设置合理的validation-query
    • 配置remove-abandoned-timeout防止连接泄漏
  2. MyBatisPlus二级缓存配置

  3. 批量操作使用executeBatch提升性能

6. 常见问题排查

6.1 连接失败问题

问题现象:SQL Server连接报错"08001"

解决方案

  1. 检查SQL Server是否启用TCP/IP协议
  2. 验证SQL Server身份验证模式(混合模式)
  3. 检查防火墙设置是否放行1433端口

6.2 事务不生效问题

问题现象:跨数据源操作时事务不回滚

原因分析:默认事务管理器只能管理单个数据源

解决方案

  1. 使用JTA实现分布式事务
  2. 拆分为多个独立事务
  3. 最终一致性方案补偿

6.3 MyBatisPlus映射问题

问题现象:SQL Server表字段映射失败

解决方案

  1. 检查@TableName注解是否正确
  2. SQL Server字段建议使用下划线命名
  3. 配置mybatis-plus.global-config.db-config.column-underline=true

7. 生产环境建议

  1. 敏感配置加密:使用jasypt加密数据源密码
  2. 多环境配置:通过profile区分开发/测试/生产环境
  3. 监控集成:配置Druid监控界面
  4. 连接泄漏检测:开启removeAbandoned相关配置
  5. 慢SQL监控:配置filter.stat.log-slow-sql=true

实际项目中,多数据源配置需要根据具体业务需求进行调整。对于读写分离场景,可以考虑使用ShardingSphere等专业中间件。在微服务架构下,更推荐将不同数据源拆分为独立服务,通过API调用实现数据交互。

返回列表