Spring集成Mybatis多数据源配置

既然在整理Mybatis那就把经常用的这个多数据源的笔记也整一下吧。

Spring集成Mybatis在之前就已经提到了。Spring集成Mybatis

集成Mybatis多数据源有两种方式:

1、创建多个SqlSessionFactory,扫描每个SqlSessionFactoryBean对应的包,形成了每个Factory对应一个数据源。

2、创建一个SqlSessionFactory,通过动态切换数据源对象,达到多数据源操作功能。

第一种方式

通过在Spring的配置文件中配置多个SqlSessionFactoryBean对象,每个对应不同的MapperScannerConfigurer,每个MapperScannerConfigurer扫描不同的包路径接口;

另外一个数据源也如上配置,只需替换对应的扫描包即可,这样调用指定包下的接口就能访问指定的数据库了。

第二种方式

创建单个SqlSessionFactory,指定默认数据源,后期查询不同的数据库切换SqlSessionFactory中数据源,如果访问次数过多,频繁切换的话,就会导致一个并发问题。

解决这个问题就应该使用并发中一些机制:如果使用锁机制的话,那么查询的效率就会降低,同时只有当线程去执行;采用ThreadLocal的话就能解决这个效率以及线程安全的问题了。

由于需切换数据源,所以在创建SqlSessionFactory时需要有几个注意的点:

1、设置数据源对象应该为一个支持切换的一个DataSource对象,我们先定义为RouteDataSource对象,由于是DataSource所以这个RouteDataSource就必须实现DataSource接口,但是又不能侵入原本数据库链接池的对象,所以这个采用装饰器模式进行装饰这个类;

2、支持动态切换,即需要一个暴露的静态方法进行切换,由于数据源对象都在这个Spring容器当中,所以这个类需拿到Spring的容器使用权(实现ApplicationContextAware接口);

3、需指定切换那个数据源,可以采用ENUM枚举进行指定,也可以通过String,都可以。

创建一个枚举类:

public enum DataSourceEnum {DATASOURCE1(null),DATASOURCE2(null);DataSource dataSource;private DataSourceEnum(DataSource dataSource) {this.dataSource =  dataSource;}public DataSource getValue() {return dataSource;}public DataSourceEnum setDataSource(DataSource dataSource) {this.dataSource  = dataSource;return this;}}

RouteDataSource类如下:

@Component("routeDataSource")
public class RouteDataSource implements DataSource,InitializingBean,ApplicationContextAware {private static final Map<DataSourceEnum,DataSource> targetDataSources = new HashMap<DataSourceEnum,DataSource>(2); //避免并发问题ThreadLocal<DataSource> targetDataSource = new ThreadLocal<DataSource>();//装时器模式进行数据源增强private static RouteDataSource route = null;public void setDataSource(DataSource targetDataSource) {this.targetDataSource.set(targetDataSource);}@Overridepublic PrintWriter getLogWriter() throws SQLException {return targetDataSource.get().getLogWriter();}@Overridepublic void setLogWriter(PrintWriter out) throws SQLException {targetDataSource.get().setLogWriter(out);}@Overridepublic void setLoginTimeout(int seconds) throws SQLException {targetDataSource.get().setLoginTimeout(seconds);}@Overridepublic int getLoginTimeout() throws SQLException {return targetDataSource.get().getLoginTimeout();}@Overridepublic Logger getParentLogger() throws SQLFeatureNotSupportedException {return targetDataSource.get().getParentLogger();}@Overridepublic <T> T unwrap(Class<T> iface) throws SQLException {return targetDataSource.get().unwrap(iface);}@Overridepublic boolean isWrapperFor(Class<?> iface) throws SQLException {return targetDataSource.get().isWrapperFor(iface);}@Overridepublic Connection getConnection() throws SQLException {return targetDataSource.get().getConnection();}@Overridepublic Connection getConnection(String username, String password) throws SQLException {return targetDataSource.get().getConnection(username, password);}//初始化枚举数据,已经默认数据源@Overridepublic void afterPropertiesSet() throws Exception {targetDataSources.put(DataSourceEnum.DATASOURCE1.setDataSource((DataSource) applicationContext.getBean("dataSource")), (DataSource) applicationContext.getBean("dataSource"));targetDataSources.put(DataSourceEnum.DATASOURCE2.setDataSource((DataSource) applicationContext.getBean("dataSource1")), (DataSource) applicationContext.getBean("dataSource1"));targetDataSource.set(targetDataSources.get(DataSourceEnum.DATASOURCE1));route = (RouteDataSource) applicationContext.getBean("routeDataSource");}private ApplicationContext applicationContext;@Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {this.applicationContext = applicationContext;}/*** @description 更改数据源方法* @param enumDataSource*/public static void setDataSource(DataSourceEnum enumDataSource) {route.setDataSource(targetDataSources.get(enumDataSource));}}

所以在调用Mybatis的接口之前,调用RouteDataSource.setDataSource(DataSourceEnum.DATASOURCE);即可切换成对应的数据源进行查询啦。

上面是一个自定义的数据源路由类,后来才发现在Spring的jdbc包下有个支持数据源切换的动态数据源类AbstractRoutingDataSource。

如果使用这个类做数据源切换,也是可以的,实现的思想以及模式都和自定义的那个是一致的;

示例:

public class ThreadLocalRountingDataSource extends AbstractRoutingDataSource {@Overrideprotected Object determineCurrentLookupKey() {// TODO Auto-generated method stub//在这里做数据源切换return DataSourceTypeManager.get();}}
//管理数据源类
public class DataSourceTypeManager {//数据源保存private static final ThreadLocal<MybatisDataSource> dataSourceTypes = new ThreadLocal<MybatisDataSource>() {@Overrideprotected MybatisDataSource initialValue() {return MybatisDataSource.JKDSJ;}};public static MybatisDataSource get() {return dataSourceTypes.get();}public static void set(MybatisDataSource dataSourceType) {dataSourceTypes.set(dataSourceType);}public static void reset() {dataSourceTypes.set(MybatisDataSource.JKDSJ);}}

这个类还是挺好用的

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/537116.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Spring文件上传

2019独角兽企业重金招聘Python工程师标准>>> Spring文件上传 1、所需依赖包&#xff1a;commons-fileupload-1.3.1.jar2、Maven配置文件pom.xml文件中加入依赖Jar包<dependency><groupId>commons-fileupload</groupId><artifactId>commons-…

中英离线翻译mac_Instant Translate for Mac-即时翻译Mac版下载 V1.3.0-PC6苹果网

即时翻译(Instant Translate)Mac版是一款Mac平台的翻译及辞典软件&#xff0c;Instant Translate支持90的语言互翻译&#xff0c;通过ControlS切换语言&#xff0c;并且支持发音功能&#xff0c;并且支持自动检测语言并进行翻译。软件特色Instant Translate的主要特点&#xff…

基于Zookeeper使用ZkClient实现分布式锁

有段时间没写博客了&#xff0c;在整理之前写过的一套自定义框架&#xff0c;并且整理好上传值github上了&#xff0c;也有一些新功能还在开发&#xff0c;欢迎大家使用&#xff1a;一个好用的Http接口请求工具组件 可能今天这篇文章跟之前的比有些跳跃性&#xff0c;一下子就…

算法题学到的一些小语言细节

1.要学会用i&#xff1b;可以简化很多代码&#xff1a;i&#xff1b;copyFromMe(i)&#xff1b;可以写成&#xff1a;copyFromeMe(i) 2.StringBuffer也跟列表一样有append函数&#xff1b; 3.if语句是分支不能进行循环&#xff0c;要写成while才能替代循环里面的判断 4. 这里的…

android 按钮带图标 阴影_android中带图标的按钮(ImageButton)怎么用

展开全部除了Android系统自带的Button按钮以外&#xff0c;还提供了带图标的按钮ImageButton要制作带图标的按钮&#xff0c;首先要在布局62616964757a686964616fe58685e5aeb931333337613163文件中定义ImageButton&#xff0c;然后通过setImageDrawable方法来设置要显示的图标。…

Zookeeper基础常用操作以及ACL权限

这次将Zookeeper的一些基础用法以及权限这块的都补充一下在这篇博客中。 上篇博客介绍了基于ZooKeeper实现的分布式锁&#xff0c;也介绍了一些ZooKeeper的节点类型以及监听机制&#xff0c;今天这里就不作过多的介绍了&#xff0c;大家也可以自行的去官方文档上看看更具体的介…

[中医经络学习一]足阳明胃经

人体有六脏&#xff08;心、肝、脾、肺、肾五脏&#xff0c;再加心包&#xff09;六腑&#xff08;胃、小肠、大肠、膀胱、胆、三焦&#xff09;&#xff0c;每个脏腑都联接着一条经络&#xff0c;一共12条经络&#xff0c;称“十二正经”&#xff0c;经络的走向在四肢两侧基本…

ThreadLocal原理解析以及是否需要调用remove方法

平常的开发过程中&#xff0c;如果有个类不是线程安全的&#xff0c;比如SimpleDateFormat&#xff0c;要使这个类在并发的过程中是线程安全的&#xff0c;那么可以将变量设置位局部变量&#xff0c;不过存在的问题就是频繁的创建对象&#xff0c;对性能和资源会有一定降低和消…

Maven基础及概念

前言 今天就来聊聊Maven的基础和一些比较概念性的东西&#xff0c;还有一些常用的Maven命令啥的&#xff0c;主要是某人脑子记不住&#xff0c;记在博客中让她自己看吧&#xff0c;省的费心给她找。 后续的文章会聊到Maven的一些比较高级用法&#xff0c;像自定义插件&#x…

织梦缩略图自动补齐绝对路径_织梦生成文章内容缩略图时自动加上域名绝对路径...

今天又接了个织梦CMS的有偿服务,客户想要后台添加文章内容的时候,缩略图自动变成带上绝对路径的格式.比如我们默认的缩略图是这样的 /uploads/allimg/150814/123P2NB-0-lp.png 他想要的效果是这样的 http://www.youwujun.com.cn/uploads/allimg/150814/123P2NB-0-lp.png大家懂我…

BUAA 436 孟竹的复习计划(二维树状数组)

题目链接&#xff1a;http://acm.buaa.edu.cn/problem/436/ 题意&#xff1a;一个数列两种操作&#xff1a;&#xff08;1&#xff09;将某个位置的数字改成另一个数字&#xff1b;&#xff08;2&#xff09;交换两个位置的数字。每次操作之后输出逆序数的个数。 思路&#xff…

Maven之pom.xml常用标签解析及镜像配置

前言 Maven仅仅是个打包工具而已&#xff0c;个人觉得没有太大必要花费在打包工具上&#xff0c;这里就列举一下个人觉得会常用标签的使用就好了&#xff0c;原理啥的基本就不太会去深度了解了&#xff0c;如果以后遇到需了解Maven工作原理的工作的话&#xff0c;到时候一定分…

idea 导入svn代码_idea导入svn项目

起初和导入git项目一样&#xff0c;file - new - project from version control - &#xff0c;这后面选 subversion。在打开的 checkout from subversion对话框中&#xff0c;输入svn地址&#xff0c;比如 svn://11.22.33.44/demo。添加一个后&#xff0c;展开新加项&#xff…

由mysql8降级到mysql5

最近在研究liferay的使用。liferay可以连接mysql数据库。电脑中装的mysql的最新版本是mysql8。于是开始按照liferay的要求进行连接。但是多番尝试后&#xff0c;均报错&#xff1a;java.sql.SQLException: java.lang.ClassCastException: java.math.BigInteger cannot be cast …

tf计算矩阵维度_tensorflow中关于 多维tensor的运算(tf.multiply, tf.matmul, tf.tensordot)...

multiply 等同与* &#xff0c;用于计算矩阵之间的element-wise 乘法&#xff0c;要求矩阵的形状必须一致(或者是其中一个维度为1)&#xff0c;否则会报错&#xff1a;import tensorflow as tfa tf.constant([1, 2, 3, 4, 5, 6, 7, 8, 9, 10,11,12], shape[2, 3, 2])b tf.con…

Maven高级之插件开发

前言 终于来到了Maven的插件开发&#xff0c;其实Maven的插件并没有想象的那么难&#xff0c;刚开始讲Maven基础的时候就演示了一下JDK是如何打包的&#xff0c;Maven打包只是在JDK打包上封装了一层而已&#xff0c;Maven也支持自定义插件开发 创建 我们先使用quickstart原型…

HTTP1.1新增了五种请求方法:OPTIONS、PUT、PATCH、DELETE、TRACE 、 CONNECT

200 &#xff08;成功&#xff09; 服务器已成功处理了请求。 通常&#xff0c;这表示服务器提供了请求的网页。 201 &#xff08;已创建&#xff09; 请求成功并且服务器创建了新的资源。 202 &#xff08;已接受&#xff09; 服务器已接受请求&#xff0c;但尚未处…

katalon进行app测试_Katalon API 测试 Demo

为何选择Katalon符合我们当下的情况&#xff0c;测试需要借助现有工具提高测试效率以及提高测试质量&#xff1b;为何不自己写代码&#xff1f;不是只有自己写的框架才是最好的&#xff0c;合适的才是最好的&#xff1b;katalon 支持ui、mobile、api 同时也支持脚本模式&#x…

Maven高级之archetype(原型/骨架)开发

前言 archetype这个的主要功能就是将写好的项目模块打包成一个原型&#xff0c;然后提供给其他人使用&#xff0c;这样别人就可以快速使用这个项目模板了。 这个东西虽然很多人都基本用不上&#xff0c;但原型这个东西用的好还是很方便的&#xff0c;能够在开发新项目上省去大…

深度学习在搜索业务中的探索与实践

本文根据美团高级技术专家翟艺涛在2018 QCon全球软件开发大会上的演讲内容整理而成&#xff0c;内容有修改。引言 2018年12月31日&#xff0c;美团酒店单日入住间夜突破200万&#xff0c;再次创下行业的新纪录&#xff0c;而酒店搜索在其中起到了非常重要的作用。本文会首先介绍…