原理:执行SQL的时候会拿到数据源,AbstractRoutingDataSource类系统预留了接口,可以根据需求来拿到对应的数据源。
一、配置多数据源
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
@Configuration public class DataSourceProxyConfig { @Bean("originOrder") @ConfigurationProperties(prefix = "spring.datasource.order") public DataSource dataSourceMaster() { return new DruidDataSource(); } @Bean("originStorage") @ConfigurationProperties(prefix = "spring.datasource.storage") public DataSource dataSourceStorage() { return new DruidDataSource(); } @Bean("originPay") @ConfigurationProperties(prefix = "spring.datasource.pay") public DataSource dataSourcePay() { return new DruidDataSource(); } @Bean(name = "order") public DataSourceProxy masterDataSourceProxy(@Qualifier("originOrder") DataSource dataSource) { return new DataSourceProxy(dataSource); } @Bean(name = "storage") public DataSourceProxy storageDataSourceProxy(@Qualifier("originStorage") DataSource dataSource) { return new DataSourceProxy(dataSource); } @Bean(name = "pay") public DataSourceProxy payDataSourceProxy(@Qualifier("originPay") DataSource dataSource) { return new DataSourceProxy(dataSource); } @Bean("dynamicDataSource") public DataSource dynamicDataSource(@Qualifier("order") DataSource dataSourceOrder, @Qualifier("storage") DataSource dataSourceStorage, @Qualifier("pay") DataSource dataSourcePay) { DynamicRoutingDataSource dynamicRoutingDataSource = new DynamicRoutingDataSource(); Map<Object, Object> dataSourceMap = new HashMap<>(3); dataSourceMap.put(DataSourceKey.ORDER.name(), dataSourceOrder); dataSourceMap.put(DataSourceKey.STORAGE.name(), dataSourceStorage); dataSourceMap.put(DataSourceKey.PAY.name(), dataSourcePay); dynamicRoutingDataSource.setDefaultTargetDataSource(dataSourceOrder); dynamicRoutingDataSource.setTargetDataSources(dataSourceMap); DynamicDataSourceContextHolder.getDataSourceKeys().addAll(dataSourceMap.keySet()); return dynamicRoutingDataSource; } @Bean @ConfigurationProperties(prefix = "mybatis") public SqlSessionFactoryBean sqlSessionFactoryBean(@Qualifier("dynamicDataSource") DataSource dataSource) { SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean(); sqlSessionFactoryBean.setDataSource(dataSource); return sqlSessionFactoryBean; } }
二、配置SqlSessionFactoryBean - 如上
三、实现自定义的DynamicRoutingDataSource
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
@Slf4j public class DynamicRoutingDataSource extends AbstractRoutingDataSource { @Override protected Object determineCurrentLookupKey() { log.info("当前数据源 [{}]", DynamicDataSourceContextHolder.getDataSourceKey()); return DynamicDataSourceContextHolder.getDataSourceKey(); } }
四、如何使用
需要与数据库交互前设置对应的数据源的key
DynamicDataSourceContextHolder.setDataSourceKey(DataSourceKey.ORDER);