简介
由于项目需要,Spring Boot要能同时连接几个不同的库,比如数据想放在Oracle,nacos的配置想放在MySQL(nacos在Issue里面提到未来可能支持多种类型的数据库,但现在由于内部的一些设计,还没能支持)。
首先想到的设计就是:
1.建立多个DataSource,MyBatis根据调用的Mapper不同,切换不同的DataSource。毕竟JDBC规范就是DataSource对应某一个数据库,DataSource负责管理和这个数据库之间的连接池。
2.JDBC规范可以生成不同的SqlSessionFactory,由应用层去切换SqlSessionFactory,然后的不同的SqlSession。这种方案肯定不好,应用层干嘛要做这种事情。
3.MyBatis Plus提供了一个多数据源的方案,这个就没啥技术难度,按照文档配置就行。至于怎么配合DataSource,这个还得详细研究下。
方案说明
这篇文章只说明第一种方案是怎么实现的,其他方案可以依据这个方案再详细设计改造下。理论上数据库访问就只涉及JDBC规范里面的几个类,能折腾的东西就是Spring Boot、Druid、MyBatis的这些东西。
这里讲下在开发之前所需要的知识点。
-
Spring Boot默认情况下不鼓励多数据源
这点可以从org.springframework.boot.autoconfigure.jdbc.DataSourceProperties
配置类中可以看出。username这些信息只有一份,Spring Boot考虑在使用时尽量做到精简,应用应该做到小而美。不过现实情况往往比较复杂,不能一厢情愿地追求最佳实践。 -
Druid-Stater遵循第一点的设计
也就是说,druid-spring-boot-starter
认为你引入了我这个包,那么你想快速上手,那么我就遵循第一点的设计,也只配置一个DataSource。所以在这点上,必须要修改这个设计,才能将Druid配置正确。
这点在DruidDataSourceAutoConfigure
和DruidDataSourceWrapper
中有所体现,DruidDataSourceWrapper
中默认注入:@Autowired private DataSourceProperties basicProperties;
这就是第一点的Spring Boot知识。
如果看到这种下面设计,其实就是注入了
DruidDataSourceWrapper
Bean,由于注解@ConfigurationProperties
有覆盖配置功效,所以指定的配置下的username之类的配置就会进行替代:@Configuration @Component public class DynamicDataSourceConfig { @Bean @ConfigurationProperties("spring.datasource.druid.xiaobin-master") public DataSource xiaobinMasterDataSource(){ return DruidDataSourceBuilder.create().build(); } @Bean @ConfigurationProperties("spring.datasource.druid.xiaobin-slave") public DataSource xiaobinSlaveDataSource(){ return DruidDataSourceBuilder.create().build(); }
当然,我为了能兼容以后的扩展,选择能形成List的配置形式,循环添加Bean。
-
AbstractRoutingDataSource
切换数据源这个事情,Spring已经做好了抽象类——org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource
。这个类通过determineCurrentLookupKey()
方法来决定是哪个key,这个key能找到的value就是对应的DataSource。
这样我们就可以轻松一点做DataSource切换功能。
源代码
本工程看时间有可能随时更新,保持最新版本。
感谢 https://gitee.com/wbsxch/ssm 提供参考。