SpringBoot如何配置动态数据源?原理+实战
在Spring Boot中配置动态数据源通常涉及以下步骤:
- 创建一个动态数据源类,比如
DynamicDataSource
,继承AbstractRoutingDataSource
并实现determineCurrentLookupKey
方法。 - 配置至少两个数据源作为动态数据源的目标。
- 将动态数据源设置为
DataSource
的目标。 - 在服务层或者数据访问层通过某种方式(如上下文持有者)切换数据源。
以下是一个简化的实例代码:
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
import javax.sql.DataSource;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class DynamicDataSource extends AbstractRoutingDataSource {
private final Map<Object, Object> dynamicTargetDataSources = new ConcurrentHashMap<>();
@Override
protected Object determineCurrentLookupKey() {
// 从ThreadLocal中获取数据源标识
return DataSourceContextHolder.getDataSourceType();
}
public void addDataSource(String key, DataSource dataSource) {
this.dynamicTargetDataSources.put(key, dataSource);
this.setTargetDataSources(dynamicTargetDataSources);
// 在添加数据源后,需要调用afterPropertiesSet()方法来更新内部的数据源映射
this.afterPropertiesSet();
}
}
// 数据源上下文持有者
public class DataSourceContextHolder {
private static final ThreadLocal<String> contextHolder = new ThreadLocal<>();
public static void setDataSourceType(String dataSourceType) {
contextHolder.set(dataSourceType);
}
public static String getDataSourceType() {
return contextHolder.get();
}
public static void clearDataSourceType() {
contextHolder.remove();
}
}
// 配置数据源和DynamicDataSource Bean
@Configuration
public class DataSourceConfig {
@Bean
public DataSource dataSource() {
DynamicDataSource dynamicDataSource = new DynamicDataSource();
// 配置默认数据源
dynamicDataSource.setDefaultTargetDataSource(primaryDataSource());
// 初始化时添加其他数据源
dynamicDataSource.addDataSource("primary", primaryDataSource());
dynamicDataSource.addDataSource("secondary", secondaryDataSource());
return dynamicDataSource;
}
@Bean
public DataSource primaryDataSource() {
// 创建并配置主数据源
return new HikariDataSource();
}
@Bean
public DataSource secondaryDataSource() {
// 创建并配置第二数据源
return new HikariDataSource();
}
}
// 使用动态数据源
@Service
public class SomeService {
@Autowired
private JdbcTemplate jdbcTemplate;
public void usePrimaryDataSource() {
DataSourceContextHolder.setDat
评论已关闭