目录
解决什么问题
一个 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 两个独立库切换,并非真实主从复制 |