在SpringBoot项目中,可以通过定义一个数据源路由来动态切换数据源。以下是一个简化的示例:
- 定义一个数据源路由类,继承
AbstractRoutingDataSource
。
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() {
return DataSourceContext.getCurrentDataSource();
}
public void addDataSource(String key, DataSource dataSource) {
this.dynamicTargetDataSources.put(key, dataSource);
this.setTargetDataSources(dynamicTargetDataSources);
this.afterPropertiesSet();
}
}
- 创建一个DataSourceContext类用于保存当前线程使用的数据源标识。
public class DataSourceContext {
private static final ThreadLocal<String> contextHolder = new ThreadLocal<>();
public static void setCurrentDataSource(String dataSourceType) {
contextHolder.set(dataSourceType);
}
public static String getCurrentDataSource() {
return contextHolder.get();
}
public static void clearDataSource() {
contextHolder.remove();
}
}
- 在配置类中配置DynamicDataSource并配置默认数据源。
@Configuration
public class DataSourceConfig {
@Bean
public DataSource dataSource() {
DynamicDataSource dynamicDataSource = new DynamicDataSource();
dynamicDataSource.setDefaultTargetDataSource(primaryDataSource()); // 默认数据源
dynamicDataSource.addDataSource("secondary", secondaryDataSource()); // 其他数据源
return dynamicDataSource;
}
@Bean
public DataSource primaryDataSource() {
// 配置主数据源
}
@Bean
public DataSource secondaryDataSource() {
// 配置第二数据源
}
}
- 在需要切换数据源的地方,调用
DataSourceContext.setCurrentDataSource()
方法。
@Service
public class DataSourceService {
@Autowired
private JdbcTemplate jdbcTemplate;
public void switchToSecondaryDataSource() {
DataSourceContext.setCurrentDataSource("secondary");
jdbcTemplate.execute("SELECT * FROM secondary_db_table"); // 使用第二数据源
DataSourceContext.clearDataSource(); // 清除数据源标识
}
}
以上代码实现了在SpringBoot项目中动态切换数据源的功能。通过DataSourceContext类保存当前线程使用的数据源标识,DynamicDataSource类根据这个标识来决