关于spring boot mybatis 多数据源的多种方法原理概述

初衷:微服务的盛行及对于mybatis的习惯。对于现有的数据+应用的架构希望寻找及总结一种灵活、扩展性好、方便的方案作为以后长期使用。

目标是可以支持多数据源、读写分离、原理配置简单。


方案1:

原理:使用mysql自带的replicationDriver来实现。replicationDriver简单来说就是存在2个connection:masterConnection和slaveConnection。当setReadonly(true)时就会把currentConnection=slaveConnection.。

配置:

jdbc.driverClassName = com.mysql.jdbc.ReplicationDriver

jdbc.url = jdbc:mysql:replication:master:3306,slave1:6603,slave2:3306(在这里可以配置多个salve,估计在自动选择slaveConnection的时候会在多个数据源间自动路由)


方案2:

原理:自己实现配置,主要做法是先配置多个dataSource,然后再DAO层中设置多个sqlsession。一个读、一个写(或者其他更多)。这样在DAO层的方法中,选择自己适合的sqlsession来操作数据库即可。这样做很灵活,数据源的选择在DAO层的方法级,灵活性很大。但如果与mybatis结合的话就显得复杂和混乱了。因为mybatis有自己的mapper,一般做法是DAO层调用mapper,如果这样还得考录如何将相应DAO方法中的sqlsession注入到mapper中使用,又或者抛弃了mapper直接使用DAO。(有人会说直接使用mapper作为DAO,这也是日常项目中的一种做法,但对于复杂的SQL构建,对于用mapper+xml的方式来做还是很复杂和浪费时间并且有一定限制的。所以才会再加一个所谓的DAO层来进行封装。这里其实就是萝卜白菜各有所爱,不深入)

这个是就实现mapper粒度的不同数据源,并且是通过原生配置不需过多自我实现:http://blog.csdn.net/ichsonx/article/details/52053003

主要是通过@mapperScan注解,当然也有标签<mapperscan>,可参考http://www.mybatis.org/spring/mappers.html#scan不过很坑爹的是,这里只有标签说明,看来国外文档的更新及时性也不怎样


方案3:

原理:借助spring的AbstractRoutingDataSource抽象类。用于动态的选择数据源。主要实现该类并重写其中的determineCurrentLookupKey()方法。

定义一个类用于存放dataSourceKey。考虑到多线程干扰,使用threadLocal.在DAO层的方法级中主动设置DBContextHolder(这个是存放key的类)使用什么数据源。接着就是像往常一样操作数据库了。这个方法说的比较粗略,因为本人感觉不会用了。因为很麻烦。

参考地址:http://www.cnblogs.com/lzrabbit/p/3750803.html

http://blog.csdn.net/catoop/article/details/50575038(这个帖子更详尽,并且要实现的类都贴出了代码,估计复制粘贴即可使用。日期是2016年1月份的)



方案4:原理:配置2个数据源(或者多个),2个transactionManager(或者多个)。就像一般配置一样,一个TX对应一个DS。再建立抽象service类,使用@Trancational(value="数据源")注释该类。使用此方法来达到控制多数据源的隔离效果。但这样数据源的隔离就存在并限制于service层级别了。在设计系统的时候对于service领域的边界设定就有一定讲究了。参考地址:http://zhuchengzzcc.iteye.com/blog/1827633



其实还有几个方案的,甚至数据源控制在DAO层的也有。但是看着看着就觉得累了,其实并不需要如此之多的方案。


个人最后给出的方案:

其实数据源控制在控制在service层就足够了。

因为有一种情况,一个service包括2个不同源的DAO时如何保证事务原子性和一致性呢?这其实就是个更大的话题了。麻烦至极。还不如数据源控制在service层,这样在一般操作数据库的情况下以及在逻辑上更顺畅。

如果真出现多数据源的事务,那就用更高层的service封装,并且再采取其他的策略来满足(例如消息记录、握手等等的方法)。

而在数据源方面尽量控制在一个服务顶多一个数据源,这个数据源是否需要读写分离等等?还不如在数据库层面上做功夫吧,就是数据库集群,这样WEB服务沟通的只是一个数据源,至于这个数据源里面的一致性、性能什么的就还是交给数据库本身来负责吧。这个职责的划分很好。

这样的一个设计,最后的结果就是一个服务顶多只有1-2个数据源(如果你处女座发病偏要读、写分离)。

这样我们就能更好的专注服务、业务逻辑,代码结构更好的交由框架给我们服务了!

猜你喜欢

转载自blog.csdn.net/ichsonx/article/details/52061608
今日推荐