Springboot整合mybatis配置多資料來源
阿新 • • 發佈:2020-08-10
1.自定義動態資料來源類繼承AbstractRoutingDataSouce類,並建立一個ThreadLocal變數,用於設定或者獲取當前資料來源的key
2.實現determineCurrentLookupKey()方法,此方法用於確定當前資料來源的key,以選擇對應的資料來源。
3.將多資料來源封裝到targetDataSources物件中,並指定預設資料來源
4.將自定義資料來源繫結到SqlSessionFactoryBean例項上;
5.自定義切面對需要的方法進行攔截,並設定資料來源的key
具體相關示例程式碼如下:
1 public class DynamicDataSource extendsAbstractRoutingDataSource { 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 protectedObject 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 }