AbstractRoutingDataSource实现动态切换数据库
时间: 2025-04-30 11:53:03 浏览: 20
### 如何使用 `AbstractRoutingDataSource` 实现 Spring Boot 动态数据源切换
为了实现动态数据源切换,可以继承 `AbstractRoutingDataSource` 并重写其 `determineCurrentLookupKey()` 方法。该方法决定了当前线程应使用的数据源键。
#### 创建自定义数据源路由类
下面是一个简单的例子展示如何创建一个名为 `DynamicRoutingDataSource` 的类:
```java
package cn.juwatech.datasource;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
public class DynamicRoutingDataSource extends AbstractRoutingDataSource {
@Override
protected Object determineCurrentLookupKey() {
return DataSourceContextHolder.getDataSource();
}
}
```
这段代码展示了如何通过获取上下文中存储的数据源名称来决定要使用的数据源[^2]。
#### 配置多个数据源
接着,在配置文件中定义多个数据源以及主数据源的选择逻辑。这里假设存在两个数据源:`primaryDS` 和 `secondaryDS`。
```yaml
spring:
datasource:
primary:
url: jdbc:mysql://localhost:3306/primary_db?useSSL=false&serverTimezone=UTC
username: root
password: secret
driver-class-name: com.mysql.cj.jdbc.Driver
secondary:
url: jdbc:mysql://localhost:3306/secondary_db?useSSL=false&serverTimezone=UTC
username: root
password: secret
driver-class-name: com.mysql.cj.jdbc.Driver
```
#### 数据源持有者工具类
还需要编写一个辅助类用于保存和读取当前线程绑定的数据源标识符:
```java
package cn.juwatech.datasource;
public class DataSourceContextHolder {
private static final ThreadLocal<String> contextHolder = new ThreadLocal<>();
public static void setDataSource(String dsName) {
contextHolder.set(dsName);
}
public static String getDataSource() {
return contextHolder.get();
}
public static void clearDataSource() {
contextHolder.remove();
}
}
```
这个工具类允许应用程序在不同地方改变当前正在使用的数据源,并确保每次请求结束时清理掉这些状态信息以防止污染其他请求[^4]。
#### 自动装配并注册到Spring容器内
最后一步是在启动类或其他合适的地方完成自动装配工作,使上述组件能被正确加载至Spring应用上下文中:
```java
@Configuration
public class DataSourceConfig {
@Bean(name="dataSource")
@Primary
public DataSource dataSource(@Qualifier("dynamicRoutingDataSource") DataSource dynamicRoutingDataSource){
return dynamicRoutingDataSource;
}
@Bean(name="dynamicRoutingDataSource")
public DataSource dynamicRoutingDataSource(
@Qualifier("primaryDataSource") DataSource primaryDataSource,
@Qualifier("secondaryDataSource") DataSource secondaryDataSource) {
Map<Object, Object> targetDataSources = new HashMap<>();
targetDataSources.put("PRIMARY", primaryDataSource);
targetDataSources.put("SECONDARY", secondaryDataSource);
DynamicRoutingDataSource routingDataSource = new DynamicRoutingDataSource();
routingDataSource.setDefaultTargetDataSource(primaryDataSource); // 设置默认数据源
routingDataSource.setTargetDataSources(targetDataSources); // 注册目标数据源映射表
return routingDataSource;
}
@Bean(name="primaryDataSource")
@ConfigurationProperties(prefix = "spring.datasource.primary")
public DataSource primaryDataSource(){
return DataSourceBuilder.create().build();
}
@Bean(name="secondaryDataSource")
@ConfigurationProperties(prefix = "spring.datasource.secondary")
public DataSource secondaryDataSource(){
return DataSourceBuilder.create().build();
}
}
```
以上就是完整的基于 `AbstractRoutingDataSource` 的多数据源解决方案示例[^3]。
阅读全文
相关推荐



















