springboot mybatis plus多數據源輕鬆搞定 (上)
在開發中經常會遇到一個程式需要調用多個資料庫的情況,總得來說分為下面的幾種情況:
- 一個程式會調用不同結構的兩個資料庫。
- 讀寫分離,兩個數據結構可能一樣高,但是不同的操作針對不同的資料庫。
- 混合情況,既有不同的結構的資料庫,也可能存在讀寫分離的情況。
下面針對第一種情況,提供一個解決方案。
解決思路
因為兩個資料庫的功能和結構不一樣,所以可以根據功能和結構把DAO分為兩個package。然後再mapperscan中指定不同的package對接不同的數據源,即可達到多個數據源的共存。
配置yml中的數據源設置
spring:
datasource:
emanage:
url: jdbc:mysql://127.0.0.1:3306/emanage?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=UTC&useAffectedRows=true
username: root
password: ******
driver-class-name: com.mysql.cj.jdbc.Driver
ehr:
url: jdbc:mysql://127.0.0.1:3306/ehr?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=UTC&useAffectedRows=true
username: root
password: ********
driver-class-name: com.mysql.cj.jdbc.Driver
為了不必要的干擾,我把druid數據源的配置部分給刪除了。
建立兩個datasource的配置
datasource1的 配置
@Configuration
@MapperScan(basePackages = {"com.emanage.ehr.mapper.emanage"},sqlSessionTemplateRef = "sqlTemplate1")
public class DataSourceConfig1 {
@Bean(name = "datasource1")
@ConfigurationProperties(prefix = "spring.datasource.emanage")
public DruidDataSource druidDataSource1()
{
return DruidDataSourceBuilder.create().build();
}
@Bean(name = "sqlFactory1")
public SqlSessionFactory sqlSessionFactory(@Qualifier("datasource1") DruidDataSource dataSource)
throws Exception
{
MybatisSqlSessionFactoryBean factoryBean = new MybatisSqlSessionFactoryBean();
factoryBean.setDataSource(dataSource);
ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
factoryBean.setMapperLocations(resolver.getResources("classpath*:mapper/emanage/**Mapper.xml"));
return factoryBean.getObject();
}
@Bean(name = "sqlTemplate1")
public SqlSessionTemplate sqlSessionTemplate(@Qualifier("sqlFactory1") SqlSessionFactory sqlSessionFactory)
{
return new SqlSessionTemplate(sqlSessionFactory);
}
}
datasource2的配置
@Configuration
@MapperScan(basePackages = {"com.emanage.ehr.mapper.ehr"},sqlSessionTemplateRef = "sqlTemplate2")
public class DataSourceConfig2 {
@Bean(name = "datasource2")
@ConfigurationProperties(prefix = "spring.datasource.ehr")
public DataSource druidDataSource1()
{
return DataSourceBuilder.create().build();
}
@Bean(name = "sqlFactory2")
public SqlSessionFactory sqlSessionFactory(@Qualifier("datasource2") DataSource dataSource)
throws Exception
{
MybatisSqlSessionFactoryBean factoryBean = new MybatisSqlSessionFactoryBean();
factoryBean.setDataSource(dataSource);
ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
factoryBean.setMapperLocations(resolver.getResources("classpath*:mapper/ehr/**Mapper.xml"));
return factoryBean.getObject();
}
@Bean(name = "sqlTemplate2")
public SqlSessionTemplate sqlSessionTemplate(@Qualifier("sqlFactory2") SqlSessionFactory sqlSessionFactory)
{
return new SqlSessionTemplate(sqlSessionFactory);
}
}
兩個datasource的配置基本上一樣。就是建立datasource,sqlsessionFactory,sqlSessionTemplate的注入。然後通過mapperscan來指定具體什麼包採用什麼數據源。然後再對應包里就和以前單數據源一樣操作即可。
注意事項:
如果用myBatis, SqlSessionFactory 部分可以使用SqlSessionFactoryBean來生成。但是如果用mybatis plus一定要用MybatisSqlSessionFactoryBean 來生成SqlSessionFactory。否則會報錯 ,無法直接通過BaseMapper去調用查詢。
如果要再不同的包中混合上XML進行調用。需要在SqlSessionFactory的配置中設置factoryBean.setMapperLocations(resolver.getResources(“classpath*:mapper/ehr/**Mapper.xml”));
優缺點:
優點:
簡單,通過簡單的設置。就可以滿足大多數的情況。
- 缺點 *:只適合多個數據源的結構完全不一樣,通過package可以分來的方式來調用,不能靈活的在一個package下面隨心所欲的調用數據源。
那麼問題來了:如果要在一個package下面,想調用哪個就調用哪個數據源怎麼辦呢?有時間了,下一篇文章寫寫另外的實現方式。
希望對初學者有價值,如果有疑問歡迎留言交流。