dynamic-datasource多数据源
dynamic-datasource多数据源
请求 → AOP 拦截 → 动态切换 → Druid 连接池 → Mapper 执行 SQL
https://baomidou.com/guides/dynamic-datasource/
pom.xml引入
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>dynamic-datasource-spring-boot-starter</artifactId>
<version>3.5.0</version>
</dependency>
application.yml数据源配置
spring:
datasource:
dynamic:
primary: master
strict: false
datasource:
master:
url: jdbc:mysql://xx.xx.xx.xx:3306/dynamic
username: root
password: 123456
driver-class-name: com.mysql.jdbc.Driver
slave_1:
url: jdbc:mysql://xx.xx.xx.xx:3307/dynamic
username: root
password: 123456
driver-class-name: com.mysql.jdbc.Driver
slave_2:
url: ENC(xxxxx)
username: ENC(xxxxx)
password: ENC(xxxxx)
driver-class-name: com.mysql.jdbc.Driver
使用@DS切换数据源
jdbcTemplate使用多数据源
@Service
@DS("slave")
public class UserServiceImpl implements UserService {
@Autowired
private JdbcTemplate jdbcTemplate;
@Override
@DS("slave_1")
public List selectByCondition() {
return jdbcTemplate.queryForList("select * from user where age >10");
}
}
Service层切换数据源
@Service
public class UserService {
@Autowired
private UserMapper userMapper;
@DS("slave_1") // 使用slave_1数据源
public List<User> getPrimaryUsers() {
return userMapper.selectList(null);
}
@DS("slave_2") // 使用slave_2数据源
public List<User> getSecondaryUsers() {
return userMapper.selectList(null);
}
}
Mapper层切换数据源
@DS("slave_2")
@Mapper
public interface SecondaryUserMapper extends BaseMapper<User> {
// 这个 Mapper 始终使用 slave_2 数据源
}
事务层切换数据源
@Transactional // 默认事务在默认数据源
@DS("slave_1")
public void updateSecondaryUser(User user) {
userMapper.updateById(user);
}
使用JdbcTemplate
- 切换数据源:DynamicDataSourceContextHolder.push("slave")
- 清理上下文:操作完成后 DynamicDataSourceContextHolder.clear(),避免后续 SQL 仍然跑在 slave 上。
import com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import javax.sql.DataSource;
@Service
public class SlaveJdbcService {
private final DataSource dataSource;
public SlaveJdbcService(DataSource dataSource) {
this.dataSource = dataSource;
}
public void createTable(String tableName) {
String sql = String.format("CREATE TABLE IF NOT EXISTS %s LIKE dev_log", tableName);
try {
// 切换到 slave 数据源
DynamicDataSourceContextHolder.push("slave");
// 使用 JdbcTemplate 执行 SQL
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
jdbcTemplate.execute(sql);
System.out.println("在 slave 库中成功创建表: " + tableName);
} finally {
// 清理上下文,避免污染后续请求
DynamicDataSourceContextHolder.clear();
}
}
}
使用场景:
•建表、DDL 等必须指定库的操作;
•特殊情况下,需要 强制路由到 slave(而不是默认的 master)。但如果只是普通的读写分离查询,推荐直接用 @DS("slave") 注解在方法或类上,代码更优雅。
如果这篇文章对你有用,可以关注本人微信公众号获取更多ヽ(^ω^)ノ ~


浙公网安备 33010602011771号