欢迎支持笔者新作:《深入理解Kafka:核心设计与实践原理》和《RabbitMQ实战指南》,同时欢迎关注笔者的微信公众号:朱小厮的博客。

欢迎跳转到本文的原文链接:https://honeypps.com/java/spring-mybatis-multi-datasource-props-4/

有时候需要在程序中动态切换数据源,那么这个系列的之前的博文所阐述的方法就不再使用了,总不能通过程序更改config.properties文件的dataSource的值,然后再重启web服务器以便加载applicationContext.xml文件。这里讲诉的是如何利用AbstractRoutingDataSource进行数据源动态切换。

首先上applicationContext.xml文件:

<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beansclasspath:/org/springframework/beans/factory/xml/spring-beans-3.0.xsdhttp://www.springframework.org/schema/aop classpath:/org/springframework/aop/config/spring-aop-3.0.xsdhttp://www.springframework.org/schema/contextclasspath:/org/springframework/context/config/spring-context-3.0.xsdhttp://www.springframework.org/schema/tx classpath:/org/springframework/transaction/config/spring-tx-3.0.xsd"><!-- IoC配置 --><!-- 扫描类包,将标注Spring注解的类自动转化Bean,同时完成Bean的注入 --><context:component-scan base-package="com.shr.dao" /><context:component-scan base-package="com.shr.service" /><!-- DAO配置 --><context:property-placeholder location="classpath:config.properties"/><bean id="mysql" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"><property name="driverClassName"  value="${mysql_driver}"/><property name="url"       value="${mysql_url}"/><property name="username"     value="${mysql_username}"/><property name="password"    value="${mysql_password}"/></bean><bean id="oracle" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"><property name="driverClassName"    value="${ora_driver}"/><property name="url"         value="${ora_url}"/><property name="username"   value="${ora_username}"/><property name="password"  value="${ora_password}"/></bean><bean id="dataSource" class="com.shr.dao.datasource.DataSources"><property name="targetDataSources"><map key-type="java.lang.String"><entry value-ref="mysql" key="MYSQL"></entry><entry value-ref="oracle" key="ORACLE"></entry></map></property><property name="defaultTargetDataSource" ref="mysql"></property></bean><bean id="vendorProperties"class="org.springframework.beans.factory.config.PropertiesFactoryBean"><property name="properties"><props><prop key="Oracle">oracle</prop><prop key="MySQL">mysql</prop></props></property></bean><bean id="databaseIdProvider" class="org.apache.ibatis.mapping.VendorDatabaseIdProvider"><property name="properties" ref="vendorProperties" /></bean><bean name="myBatisSQLInterceptor" class="com.shr.dao.MyBatisSQLInterceptor"></bean><bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"><property name="dataSource" ref="dataSource" /><property name="typeAliasesPackage" value="com.shr.dao.pojo,com.shr.dao.model" /><property name="databaseIdProvider" ref="databaseIdProvider" /><property name="mapperLocations"><list><value>classpath:com/shr/dao/resources/mappers/*_mapper.xml</value></list></property><!-- <property name="configLocation" value="/WEB-INF/mybatis-config.xml"/> --><property name="typeHandlersPackage" value="com.shr.dao" /><property name="plugins"><list><ref bean="myBatisSQLInterceptor"/></list></property></bean><!-- 配置事务管理器 --><tx:annotation-driven/><bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="${dataSource}"/></bean><bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"><property name="basePackage" value="com.shr.dao.mapper"/><property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/> <!-- <property name="markerInterface" value="com.shr.dao.mapper.ITemplateMapper"/> --></bean>
</beans>

我们可以观察到文件中多了一段:

 <bean id="dataSource" class="com.shr.dao.datasource.DataSources"><property name="targetDataSources"><map key-type="java.lang.String"><entry value-ref="mysql" key="MYSQL"></entry><entry value-ref="oracle" key="ORACLE"></entry></map></property><property name="defaultTargetDataSource" ref="mysql"></property></bean>

而且sqlSessionFactory的dataSource是关联到上面这段内容的,而不是通过${dataSource}读取config.properties文件的内容获取的。

这个com.shr.dao.datasource.DataSources是自定义的类,继承自AbstractRoutingDataSource类,实现其determineCurrentLookupKey()方法。

代码如下:

package com.shr.dao.datasource;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
public class DataSources extends AbstractRoutingDataSource
{@Overrideprotected Object determineCurrentLookupKey(){return DataSourceSwitch.getDataSourceType();}
}
package com.shr.dao.datasource;public class DataSourceSwitch
{private static final ThreadLocal<String> contextHolder = new ThreadLocal<String>();public static void setDataSourceType(String dataSourceType){contextHolder.set(dataSourceType);}public static String getDataSourceType(){return contextHolder.get();}public static void clearDataSourceType(){contextHolder.remove();}
}
package com.shr.dao.datasource;public class DataSourceInstances
{public static final String MYSQL="MYSQL";public static final String ORACLE="ORACLE";
}

同样,我们通过一个junit测试用例进行验证:

package com.shr.dao.datasource;import java.util.List;import javax.inject.Inject;import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.transaction.TransactionConfiguration;
import org.springframework.transaction.annotation.Transactional;import com.shr.dao.datasource.DataSourceInstances;
import com.shr.dao.datasource.DataSourceSwitch;
import com.shr.dao.model.userManage.UserListInfo;
import com.shr.service.userManage.UserManageService;@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("file:WebContent/WEB-INF/applicationContext.xml")
@Transactional
@TransactionConfiguration(transactionManager="transactionManager",defaultRollback=false)
public class DynamicDataSourceTest
{@Injectprivate UserManageService userManageService;@Testpublic void test(){DataSourceSwitch.setDataSourceType(DataSourceInstances.MYSQL);List<UserListInfo> list = userManageService.getUserListInfo();for(UserListInfo user : list){System.out.println(user.getUser_name());}}
}

通过改变DataSourceSwitch.setDataSourceType(DataSourceInstances.ORACLE);可以转换不同的数据源.

欢迎跳转到本文的原文链接:https://honeypps.com/java/spring-mybatis-multi-datasource-props-4/

欢迎支持笔者新作:《深入理解Kafka:核心设计与实践原理》和《RabbitMQ实战指南》,同时欢迎关注笔者的微信公众号:朱小厮的博客。

Spring+Mybatis多数据源配置(四)——AbstractRoutingDataSource实现数据源动态切换相关推荐

  1. Spring Boot多数据源配置并通过注解实现动态切换数据源

    文章目录 1. AbstractRoutingDataSource类介绍 2. ThreadLocal类介绍 3. 环境准备 3.1 数据库准备 3.2 项目创建 4. 具体实现 4.1 定义数据源枚 ...

  2. spring,mybatis事务管理配置与@Transactional注解使用[转]

    spring,mybatis事务管理配置与@Transactional注解使用[转] spring,mybatis事务管理配置与@Transactional注解使用 概述 事务管理对于企业应用来说是至 ...

  3. spring,mybatis事务管理配置与@Transactional注解使用

    spring,mybatis事务管理配置与@Transactional注解使用 概述 事务管理对于企业应用来说是至关重要的,即使出现异常情况,它也可以保证数据的一致性. Spring Framewor ...

  4. 润乾报表 多数据源配置报错:数据源无数据库连接,且未设定数据连接工厂

    润乾报表 多数据源配置报错:数据源无数据库连接,且未设定数据连接工厂 具体报错如下图所示: 排查方法: 1.确定连接池配置是对的,包括URL 用户名 密码 2.确定数据库驱动jar放到了Tomcat的 ...

  5. 2 数据源配置_论多数据源(读写分离)的实现方案

    好的,作为一个合格的bug生产者,我们直接进入主题,多数据源和读写分离实现方案. 首先多数据源和读写分离什么时候我们才需要呢? 多数据源:一个单体项目过于复杂,需要操作多个业务库的时候,就需要多数据源 ...

  6. hikari数据源配置类_SpringBoot多数据源配置详解

    开发环境:JDK1.8+SpringBoot2.1.4.RELEASE+Oracle 这里我们假设要使用两个数据源分别为:master和slave. pom.xml 依赖包 org.springfra ...

  7. spring+mybatis+springmvc项目配置

    项目下web.xml <?xml version="1.0" encoding="UTF-8"?> <web-app version=&quo ...

  8. springboot多数据源配置_SpringBoot-配置多数据源

    1.4.springboot整合多数据源 你们在项目中有使用到多数据源吗? 4.4.1配置文件中新增两个数据源 spring.datasource.test1.driverClassName = co ...

  9. Spring Boot 入门系列(二十三)整合Mybatis,实现多数据源配置!

    d之前介绍了Spring Boot 整合mybatis 使用注解方式配置的方式实现增删改查以及一些复杂自定义的sql 语句 .想必大家对spring boot 项目中,如何使用mybatis 有了一定 ...

  10. Spring MVC+Mybatis 多数据源配置

    文章来自:https://www.jianshu.com/p/fddcc1a6b2d8 1. 继承AbstractRoutingDataSource AbstractRoutingDataSource ...

最新文章

  1. City of Angels
  2. 深入struts2.0(七)--ActionInvocation接口以及3DefaultActionInvocation类
  3. 符号化Symbol(符号)体系(转载)
  4. matlab的guide怎么添加函数,整理:matlab如何添加m_map工具箱
  5. 【循序渐进学Python】6.Python中的函数
  6. Jenkins 2.322 安装 自定义插件
  7. python单词的含义-Python常用英文单词有哪些?
  8. [转] 跨域资源共享 CORS 详解
  9. JSF+Spring+Hibernate整合要点
  10. chrome extensions快捷键shortcuts配置
  11. scrollTop、scrollHeight、offsetTop、offsetHeight、clientTop、clientHeight区别
  12. Google Java Style Guide
  13. 2023西安电子科技大学计算机考研信息汇总
  14. Vue - 姓名案例
  15. Adobe2022更新,打开photoshop总是提示需要访问钥匙串秘钥怎么解决?
  16. 点击html内任意图片放大,再点击关闭放大图片
  17. 页面跳转javascript操作referer
  18. java 获取服务器信息
  19. 家庭收支账户小程序设计
  20. ElasticSearch最佳入门实践(一)什么是ElasticSearch

热门文章

  1. LinkedBlockingQueue源码
  2. c++读取utf8文件_经常在日常工作中处理统一码文件(or其他编码)?这篇必读
  3. 论云计算机下的中小企业会计信息化建设,中小企业云会计信息化的建议论文
  4. java11开源中国,Java 11 正式发布!
  5. 解决IntelliJ IDEA报错Error:Cannot determine path to ‘tools.jar‘ library for 17 (C:\Program Files\Java\jd
  6. 210312阶段三通过sqlite3源码安装sqlite3
  7. linux常用命令和选项
  8. 启动php出现的错误
  9. HDU 1199 amp;amp; ZOJ 2301 线段树离散化
  10. C#检查json格式是否合法