在开发中经常会遇到一个程序需要调用多个数据库的情况,总得来说分为下面的几种情况:
下面针对第一种情况,提供一个解决方案。
因为两个数据库的功能和结构不一样,所以可以根据功能和结构把DAO分为两个package。然后再mapperscan中指定不同的package对接不同的数据源,即可达到多个数据源的共存。
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数据源的配置部分给删除了。
@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); } }
@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下面,想调用哪个就调用哪个数据源怎么办呢?有时间了,下一篇文章写写另外的实现方式。
希望对初学者有价值,如果有疑问欢迎留言交流。