1. 程式人生 > 實用技巧 >Springboot整合mybatis配置多資料來源

Springboot整合mybatis配置多資料來源

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     }