JHHK

欢迎来到我的个人网站
行者常至 为者常成

bug菌_多数据源

目录

解决什么问题

一个 Spring Boot 项目同时连接多个数据库,并在代码中按需切换。

场景 说明
读写分离 主库写,从库读,分摊数据库压力
业务分库 不同业务数据放在不同库
数据同步 避免同步任务的 IO 影响主业务库

传统做法要为每个库分别创建 DataSource、SqlSessionFactory 和事务管理器,新增一个库就要复制一整套配置。文章用 dynamic-datasource-spring-boot-starter 省掉这些样板代码,只保留配置和注解。

快速集成

环境:JDK 1.8、Spring Boot 2.3.1、starter 3.5.0。

1. 引入依赖

<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>dynamic-datasource-spring-boot-starter</artifactId>
    <version>3.5.0</version>
</dependency>

2. 配置数据源

spring:
  datasource:
    dynamic:
      primary: master   # 默认数据源
      strict: false     # true 匹配不到数据源则报错;false 回落到默认库
      datasource:
        master:
          driver-class-name: com.mysql.cj.jdbc.Driver
          url: jdbc:mysql://localhost:3306/springboot_db?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf-8
          username: root
          password: 123456
        slave_1:
          driver-class-name: com.mysql.cj.jdbc.Driver
          url: jdbc:mysql://127.0.0.1:3306/test_db2?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf-8
          username: root
          password: 123456

引入依赖后不需要再手写数据源配置类。

约定:

  • 默认数据源名为 master,可用 primary 修改。
  • 下划线前是组名,slave_1、slave_2 同属 slave 组,使用组名切换时会负载均衡。

@DS 切换数据源

@DS("slave_1")   // 指定具体数据源
@DS("slave")     // 指定组名,组内负载均衡
  • 可标在类或方法上;两者同时存在时,方法上的优先。
  • 不写 @DS,使用 primary 指定的数据源。
@Service
@DS("master") // 默认走主库
public class UserDbServiceImpl implements UserDbService {

    @Autowired
    private UserDbOneMapper userDbOneMapper;

    @Autowired
    private UserDbTwoMapper userDbTwoMapper;

    public List<UserDbOneEntity> queryUserListDbOne() {
        return userDbOneMapper.selectList(new QueryWrapper<>());
    }

    @DS("slave_1") // 方法级注解覆盖类级注解
    public List<UserDbTwoEntity> queryUserListDbTwo() {
        return userDbTwoMapper.selectList(new QueryWrapper<>());
    }
}

实体分别用 @TableName("db_user1")、@TableName("db_user2") 映射两张表,Controller 再暴露对应查询接口即可。

验证与注意事项

启动日志确认两个库都已注册:

dynamic-datasource initial loaded [2] datasource,primary datasource named [master]

分别请求两个接口,返回 张三(db1)和 李四(db2);合并接口能同时返回两边数据,说明切换生效。

注意点 说明
primary 必须指向真实存在的数据源
strict 生产建议设为 true,避免匹配失败后静默走主库
@DS 只是路由 读方法要自己标 @DS("slave"),写方法留在 master,读写分离才不会自动失效
版本匹配 示例为 Spring Boot 2.x + starter 3.5.0;Spring Boot 3 需用 4.x
演示范围 文章是 springboot_db 与 test_db2 两个独立库切换,并非真实主从复制




R
Valine - A simple comment system based on Leancloud.