Java学习Spring boot

SpringMVC+Mybatis 如何配置多个数据源并切换?

2019-03-28  本文已影响0人  Java碎碎念

最近公司一个项目需要连接两个数据库(A和B)操作,有的模块查询A库,有的模块查询B库,因此需要改造下,项目后台用的是SpringMVC+Mybatis+MySQL架构,折腾了两天后终于搞定了,在这里记录过改造过程。

使用场景

多数据源的使用的场景一般有:

主从数据库切换

读写分离

兼容旧库

实现原理

Spring2.x的版本中采用Proxy模式,就是在方案中实现一个虚拟的数据源,并且用它来封装数据源选择逻辑,这样就可以有效地将数据源选择逻辑从Client中分离出来。Client提供选择所需的上下文,由虚拟的DynamicDataSource根据Client提供的上下文来实现数据源的选择。

具体的实现是虚拟的DynamicDataSource仅需继承AbstractRoutingDataSource实现determineCurrentLookupKey(),该方法返回需要使用的DataSource的key值,然后根据这个key从resolvedDataSources这个map里取出对应的DataSource,如果找不到则用默认的resolvedDefaultDataSource。

详细实现过程

修改spring的配置文件

配置文件里需要配置多个数据源,改造后主要配置如下:

destroy-method="close"scope="singleton">

<!--当连接池中的连接耗尽的时候c3p0一次同时获取的连接数。Default: 3 -->

<!--初始化时获取三个连接,取值应在minPoolSize与maxPoolSize之间。Default: 3 -->

<!--最大空闲时间,60秒内未使用则连接被丢弃。若为0则永不丢弃。Default: 0 -->

<!--连接池中保留的最大连接数。Default: 15 -->

<!--两次连接中间隔时间,单位毫秒。Default: 1000 -->

<!--定义在从数据库获取新连接失败后重复尝试的次数。Default: 30 -->

false -->

destroy-method="close"scope="singleton">

<!--当连接池中的连接耗尽的时候c3p0一次同时获取的连接数。Default: 3 -->

<!--初始化时获取三个连接,取值应在minPoolSize与maxPoolSize之间。Default: 3 -->

<!--最大空闲时间,60秒内未使用则连接被丢弃。若为0则永不丢弃。Default: 0 -->

<!--连接池中保留的最大连接数。Default: 15 -->

<!--两次连接中间隔时间,单位毫秒。Default: 1000 -->

<!--定义在从数据库获取新连接失败后重复尝试的次数。Default: 30 -->

false -->

<!-- 动态数据源 -->

class="org.springframework.jdbc.datasource.DataSourceTransactionManager">

<!-- MyBatis ORM operation class -->

classpath*:com/test/**/*Mapper.xml

添加动态数据源管理类

DynamicDataSource类继承AbstractRoutingDataSource,实现determineCurrentLookupKey()方法。

packagecom.test.util;

importcom.test.util.CustomerContextHolder;

importorg.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;

/**

* 动态数据源管理类

*

*/

publicclassDynamicDataSourceextendsAbstractRoutingDataSource{

@Override

protectedObjectdetermineCurrentLookupKey(){

returnCustomerContextHolder.getCustomerType();

}

}

数据源切换类

CustomerContextHolder类可以实现数据源A和B的切换,数据源标识保存在线程变量中,避免多线程操作数据源时互相干扰

package com.test.util;

/**

* 数据源切换类

*

*/

publicclassCustomerContextHolder{

publicstaticfinal String DATA_SOURCE_DEFAULT ="dataSourceTargetA";

publicstaticfinal String DATA_SOURCE_B ="dataSourceTargetB";

privatestaticfinal ThreadLocal contextHolder =newThreadLocal();

publicstaticvoidsetCustomerType(String customerType){

contextHolder.set(customerType);

}

publicstaticStringgetCustomerType(){

returncontextHolder.get();

}

publicstaticvoidclearCustomerType(){

contextHolder.remove();

}

}

使用多数据源代码

下面是Controller层代码,需要查询B数据源,查询完成后切换为默认数据源A,具体代码如下:

/**

* 订单列表查询,查询B数据源

*

*@paramrequest

*@return

*/

@RequestMapping(value ="/list")

publicStringlist(HttpServletRequest request, Integer cId) {

//设置数据源B

CustomerContextHolder.setCustomerType(CustomerContextHolder.DATA_SOURCE_B);

List orderList = salaryBillService.getSalaryOrderByOrgId(cId);

request.setAttribute("orderList", orderList);

//切换回默认数据源A

CustomerContextHolder.setCustomerType(CustomerContextHolder.DATA_SOURCE_DEFAULT);

return"/jsp/order";

}

上述四步操作完成后即可实现SpringMVC+Mybatis配置多个数据源并切换,有问题欢迎留言沟通哦!

推荐阅读

1.Spring Boot 2.X 如何优雅的解决跨域问题?

2.Redis Cluster搭建高可用Redis服务器集群

3.为什么单线程的Redis这么快?

4.Spring Boot集成spring session实现session共享

5.Spring Boot入门-快速搭建web项目

6.Spring Boot2.0整合Redis

7.一篇文章搞定SpringMVC参数绑定

限时领取免费Java相关资料,涵盖了Java、Redis、MongoDB、MySQL、Zookeeper、Spring Cloud、Dubbo/Kafka、Hadoop、Hbase、Flink等高并发分布式、大数据、机器学习等技术。

关注下方公众号即可免费领取:

上一篇 下一篇

猜你喜欢

热点阅读