1.自定义动态数据源类继承AbstractRoutingDataSouce类,并创建一个ThreadLocal变量,用于设置或者获取当前数据源的key
2.实现determineCurrentLookupKey()方法,此方法用于确定当前数据源的key,以选择对应的数据源。
3.将多数据源封装到targetDataSources对象中,并指定默认数据源
4.将自定义数据源绑定到SqlSessionFactoryBean实例上;
5.自定义切面对需要的方法进行拦截,并设置数据源的key
具体相关示例代码如下:
1 public class DynamicDataSource extends AbstractRoutingDataSource { 2 3 public static final String DB1_DATA_SOURCE = "db1DataSource"; 4 public static final String DB2_DATA_SOURCE = "db2DataSource"; 5 6 private static final ThreadLocal<String> CURRENT_DATA_SOURCE = new ThreadLocal<>(); 7 8 /** 9 * 设置当前数据源 10 * @param dataSourceName 11 */ 12 public static void setDataSource(String dataSourceName) { 13 CURRENT_DATA_SOURCE.set(dataSourceName); 14 } 15 16 public static String getDataSource(){ 17 return CURRENT_DATA_SOURCE.get(); 18 } 19 @Override 20 protected Object determineCurrentLookupKey() { 21 String dataSource = CURRENT_DATA_SOURCE.get(); 22 if(StringUtils.isEmpty(dataSource)){ 23 return DB1_DATA_SOURCE; 24 } 25 return dataSource; 26 } 27 }
1 @Bean 2 public DynamicDataSource dataSource( 3 @Qualifier(DynamicDataSource.DB1_DATA_SOURCE) DataSource db1DataSource, 4 @Qualifier(DynamicDataSource.DB2_DATA_SOURCE) DataSource db2DataSource){ 5 6 // logger.info("配置动态数据源:db1DataSource:{},db2DataSource:{}",db1DataSource,db2DataSource); 7 DynamicDataSource dynamicDataSource = new DynamicDataSource(); 8 Map<Object,Object> targetDataSources = new HashMap<>(); 9 targetDataSources.put(DynamicDataSource.DB1_DATA_SOURCE,db1DataSource); 10 targetDataSources.put(DynamicDataSource.DB2_DATA_SOURCE,db2DataSource); 11 dynamicDataSource.setDefaultTargetDataSource(db1DataSource); 12 dynamicDataSource.setTargetDataSources(targetDataSources); 13 dynamicDataSource.afterPropertiesSet(); 14 return dynamicDataSource; 15 } 16 17 @Bean 18 public SqlSessionFactoryBean sqlSessionFactoryBean(DynamicDataSource dynamicDataSource) throws IOException { 19 logger.info("配置SqlSessionFactoryBean:{}",dynamicDataSource.determineCurrentLookupKey()); 20 SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean(); 21 org.apache.ibatis.session.Configuration configuration = new org.apache.ibatis.session.Configuration(); 22 configuration.setLogImpl(StdOutImpl.class); 23 configuration.setMapUnderscoreToCamelCase(true); 24 configuration.setCallSettersOnNulls(true); 25 sqlSessionFactoryBean.setConfiguration(configuration); 26 sqlSessionFactoryBean.setDataSource(dynamicDataSource); 27 ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(); 28 sqlSessionFactoryBean.setMapperLocations(resolver.getResources(mapperLocations)); 29 return sqlSessionFactoryBean; 30 }
如果多数据源中如果除了纯db连接配置还有JNDI的数据源,可以对数据源做如下处理
1 @Primary 2 @Bean(name = DynamicDataSource.DB1_DATA_SOURCE) 3 @ConfigurationProperties(prefix = DB1_DATA_SOURCE_PREFIX) 4 public DataSource db1DataSource() throws NamingException { 5 String jndiName = jndi1DataSource.getJndiName(); 6 if (!StringUtils.isEmpty(jndiName)){ 7 logger.info("db1DataSource使用的JNDI数据源"); 8 return jndiDataSource(jndiName); 9 } 10 return DataSourceBuilder.create().build(); 11 }
原文:https://www.cnblogs.com/fallmwu/p/13468609.html