一、核心方案对比
方案特点与适用场景: • 动态路由:适合高频切换场景(如读写分离) • 显式装配:适合独立操作不同库(如主业务库+日志库) • 三方库方案:适合快速集成场景
二、动态数据源路由(AbstractRoutingDataSource)
核心代码
// 1. 数据源上下文
public class DataSourceContext {
private static final ThreadLocal CONTEXT = new ThreadLocal<>();
public static void set(String ds) { CONTEXT.set(ds); }
public static String get() { return CONTEXT.get(); }
public static void clear() { CONTEXT.remove(); }
}
// 2. 动态数据源
public class DynamicDataSource extends AbstractRoutingDataSource {
@Override
protected Object determineCurrentLookupKey() {
return DataSourceContext.get();
}
}
// 3. 配置类
@Configuration
@EnableTransactionManagement
public class DataSourceConfig {
@Bean
@ConfigurationProperties("spring.datasource.master")
DataSource masterDataSource() {
return DataSourceBuilder.create().build();
}
@Bean
@ConfigurationProperties("spring.datasource.slave")
DataSource slaveDataSource() {
return DataSourceBuilder.create().build();
}
@Bean
DataSource dynamicDataSource() {
Map
三、显式多数据源装配
实现代码
@Configuration
public class MultiDataSourceConfig {
@Primary
@Bean("primaryDS")
@ConfigurationProperties("spring.datasource.primary")
public DataSource primaryDataSource() {
return DataSourceBuilder.create().build();
}
@Bean("secondaryDS")
@ConfigurationProperties("spring.datasource.secondary")
public DataSource secondaryDataSource() {
return DataSourceBuilder.create().build();
}
@Bean("primaryJdbc")
public JdbcTemplate primaryJdbc(@Qualifier("primaryDS") DataSource ds) {
return new JdbcTemplate(ds);
}
@Bean("secondaryJdbc")
public JdbcTemplate secondaryJdbc(@Qualifier("secondaryDS") DataSource ds) {
return new JdbcTemplate(ds);
}
}
四、MyBatis-Plus多数据源插件
快速集成
- 添加依赖:
com.baomidou
dynamic-datasource-spring-boot-starter
3.5.1
- 配置YAML:
spring:
datasource:
dynamic:
primary: master
datasource:
master:
url: jdbc:mysql://localhost:3306/main
username: root
password: 123456
slave:
url: jdbc:mysql://192.168.1.100:3306/logs
username: log_user
password: log_pass
- 注解使用:
@Service
public class OrderService {
@DS("master") // 默认数据源
public void createOrder(Order order) {
// 使用主库
}
@DS("slave")
public List getLogs() {
// 使用从库
}
}
五、方案选型建议
维度 | 动态路由 | 显式装配 | MyBatis-Plus |
---|---|---|---|
切换灵活性 | ⭐⭐⭐⭐⭐ | ⭐⭐ | ⭐⭐⭐⭐ |
配置复杂度 | ⭐⭐⭐⭐ | ⭐⭐ | ⭐ |
事务管理 | 需要自定义 | 独立管理 | 自动支持 |
学习成本 | 高 | 中 | 低 |
避坑指南:
- 动态数据源需配合@Transactional(propagation = Propagation.NOT_SUPPORTED)使用
- 显式装配时注意事务管理器绑定
- MyBatis-Plus多数据源不支持嵌套事务
选择最适合业务的方案,才是架构设计的真谛! ?