Spring Boot 整合 MyBatis-Plus 实现多数据源的完整示例

在现代企业级应用开发中,多数据源的需求非常常见。例如,系统可能需要连接多个数据库(如 MySQL 和 Oracle),或者需要实现读写分离垂直分库等架构设计。MyBatis-Plus 作为 MyBatis 的增强工具,提供了对多数据源的便捷支持。本文将详细介绍如何在 Spring Boot 项目中整合 MyBatis-Plus 实现多数据源的完整配置和使用方法。


一、多数据源的应用场景

多数据源的典型应用场景包括:

  1. 读写分离:将读操作和写操作分配到不同的数据库实例,提升系统性能。
  2. 垂直分库:根据业务模块将数据拆分到不同的数据库中,例如用户模块连接 MySQL,订单模块连接 PostgreSQL。
  3. 混合数据源:同时连接关系型数据库(如 MySQL)和时序数据库(如 TDengine),满足多样化的数据存储需求。
  4. 测试环境与生产环境隔离:通过多数据源配置,确保开发、测试和生产环境的数据隔离。

二、技术选型与依赖配置

1. 核心依赖

在 Spring Boot 项目中,我们需要引入以下关键依赖:

<!-- Spring Boot 基础依赖 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter</artifactId>
</dependency>

<!-- MyBatis-Plus 依赖 -->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.5.9</version>
</dependency>

<!-- 动态数据源支持 -->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>dynamic-datasource-spring-boot-starter</artifactId>
    <version>4.3.1</version>
</dependency>

<!-- 数据库驱动(以 MySQL 和 Oracle 为例) -->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.33</version>
</dependency>

<dependency>
    <groupId>com.oracle.database.jdbc</groupId>
    <artifactId>ojdbc8</artifactId>
    <version>19.8.0.0</version>
</dependency>

<!-- 连接池(推荐使用 HikariCP 或 Druid) -->
<dependency>
    <groupId>com.zaxxer</groupId>
    <artifactId>HikariCP</artifactId>
    <version>5.1.0</version>
</dependency>

三、配置多数据源

1. 配置文件(application.yml

application.yml 中配置多数据源的基本信息:

spring:
  datasource:
    dynamic:
      primary: master  # 设置默认数据源
      strict: true     # 严格模式(未匹配到数据源则抛出异常)
      datasource:
        master:
          url: jdbc:mysql://localhost:3306/master_db?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC
          username: root
          password: 123456
          driver-class-name: com.mysql.cj.jdbc.Driver
        slave:
          url: jdbc:mysql://localhost:3306/slave_db?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC
          username: root
          password: 123456
          driver-class-name: com.mysql.cj.jdbc.Driver
        oracle:
          url: jdbc:oracle:thin:@//localhost:1521/orclpdb1
          username: system
          password: oracle_password
          driver-class-name: oracle.jdbc.driver.OracleDriver

2. 高级配置(可选)

  • 连接池参数:为每个数据源单独配置连接池(如最大连接数、超时时间)。
  • 日志输出:开启 SQL 日志以便调试:
    mybatis-plus:
      configuration:
        log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
    

四、代码实现

1. 创建 Mapper 接口

主数据源 Mapper(Master)
@Mapper
public interface MasterUserMapper extends BaseMapper<User> {
    @Select("SELECT * FROM user")
    List<User> getMasterUsers();
}
从数据源 Mapper(Slave)
@Mapper
public interface SlaveOrderMapper extends BaseMapper<Order> {
    @Select("SELECT * FROM order")
    List<Order> getSlaveOrders();
}
Oracle 数据源 Mapper
@Mapper
public interface OracleProductMapper extends BaseMapper<Product> {
    @Select("SELECT * FROM product")
    List<Product> getOracleProducts();
}

2. Service 层使用数据源

通过 @DS 注解动态切换数据源:

@Service
public class DataService {

    @Autowired
    private MasterUserMapper masterUserMapper;

    @Autowired
    private SlaveOrderMapper slaveOrderMapper;

    @Autowired
    private OracleProductMapper oracleProductMapper;

    // 使用默认数据源(master)
    public List<User> getUsers() {
        return masterUserMapper.getMasterUsers();
    }

    // 切换到从数据源(slave)
    @DS("slave")
    public List<Order> getOrders() {
        return slaveOrderMapper.getSlaveOrders();
    }

    // 切换到 Oracle 数据源
    @DS("oracle")
    public List<Product> getProducts() {
        return oracleProductMapper.getOracleProducts();
    }
}

3. 事务管理

如果需要在多个数据源之间执行事务操作,需使用 @DSTransactional 注解:

@Service
public class TransactionalService {

    @Autowired
    private MasterUserMapper masterUserMapper;

    @Autowired
    private SlaveOrderMapper slaveOrderMapper;

    @DS("master")
    @DSTransactional
    public void transactionalOperation() {
        masterUserMapper.insert(new User("Alice", 25));
        slaveOrderMapper.insert(new Order("Order-001", 100));
    }
}

五、高级配置与优化

1. 连接池配置

为每个数据源单独配置连接池参数(以 HikariCP 为例):

spring:
  datasource:
    dynamic:
      datasource:
        master:
          hikari:
            maximum-pool-size: 20
            connection-timeout: 30000
        slave:
          hikari:
            maximum-pool-size: 15
            connection-timeout: 30000

2. 数据源路由策略

MyBatis-Plus 提供了灵活的路由策略,例如:

  • 基于线程上下文的切换:通过 DynamicDataSourceContextHolder 手动设置当前线程的数据源。
  • 基于 AOP 的自动切换:通过 @DS 注解自动绑定数据源。

六、注意事项

  1. 事务一致性

    • 跨数据源的事务需谨慎处理,建议仅在必要时使用 @DSTransactional
    • 如果事务涉及多个数据源,需确保所有操作在同一个事务上下文中。
  2. 注解优先级

    • 数据源注解的优先级为:方法注解 > 类注解 > 默认数据源
  3. 连接池监控

    • 推荐使用 Druid 或 HikariCP 的监控功能,实时查看连接池状态。
  4. 性能优化

    • 合理配置连接池的最大连接数和空闲连接数,避免资源浪费或连接不足。

七、总结

通过 Spring Boot 整合 MyBatis-Plus 的多数据源功能,开发者可以轻松实现复杂的数据访问需求。本文通过完整的配置步骤、代码示例和注意事项,帮助读者快速上手多数据源的配置与使用。在实际开发中,建议根据业务需求选择合适的数据库类型和路由策略,同时关注性能优化和事务一致性,以构建高效、稳定的系统架构。

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐