1.配置两个不同的数据源,如下

<!-- 数据源配置1 -->
<bean id="testDataSource1" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
<property name="driverClassName" value="${db.driver}" />
<property name="url" value="${unity.db.jdbc.url}" />
<property name="username" value="${db.login.name}"></property>
<property name="password" value="${db.login.password}" />
<property name="filters" value="${db.filters}"></property>
<property name="maxActive" value="${db.pool.maxActive}"></property>
<property name="initialSize" value="${db.pool.initialSize}"></property>
<property name="minIdle" value="${db.pool.minIdle}"></property>
<property name="maxWait" value="${db.maxWait}"></property>
<property name="timeBetweenEvictionRunsMillis" value="${db.timeBetweenEvictionRunsMillis}"></property>
<property name="minEvictableIdleTimeMillis" value="${db.minEvictableIdleTimeMillis}"></property>
<property name="validationQuery" value="${db.validationQuery}"></property>
<property name="testWhileIdle" value="${db.testWhileIdle}"></property>
<property name="testOnBorrow" value="${db.testOnBorrow}"></property>
<property name="testOnReturn" value="${db.testOnReturn}"></property>
<property name="poolPreparedStatements" value="${db.poolPreparedStatements}"></property>
<property name="maxOpenPreparedStatements" value="${db.maxOpenPreparedStatements}"></property>
<!-- 监控数据库 -->
<property name="proxyFilters">
<list>
<ref bean="log-filter" />
</list>
</property>

</bean>

<!-- 数据源配置2 -->
<bean id="testDataSource2" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
<property name="driverClassName" value="${db.driver}" />
<property name="url" value="${pub.db.jdbc.url}" />
<property name="username" value="${db.login.name}"></property>
<property name="password" value="${db.login.password}" />
<property name="filters" value="${db.filters}"></property>
<property name="maxActive" value="${db.pool.maxActive}"></property>
<property name="initialSize" value="${db.pool.initialSize}"></property>
<property name="minIdle" value="${db.pool.minIdle}"></property>
<property name="maxWait" value="${db.maxWait}"></property>
<property name="timeBetweenEvictionRunsMillis" value="${db.timeBetweenEvictionRunsMillis}"></property>
<property name="minEvictableIdleTimeMillis" value="${db.minEvictableIdleTimeMillis}"></property>
<property name="validationQuery" value="${db.validationQuery}"></property>
<property name="testWhileIdle" value="${db.testWhileIdle}"></property>
<property name="testOnBorrow" value="${db.testOnBorrow}"></property>
<property name="testOnReturn" value="${db.testOnReturn}"></property>
<property name="poolPreparedStatements" value="${db.poolPreparedStatements}"></property>
<property name="maxOpenPreparedStatements" value="${db.maxOpenPreparedStatements}"></property>
<!-- 监控数据库 -->
<property name="proxyFilters">
<list>
<ref bean="log-filter" />
</list>
</property>

</bean>

2.定义一个类继承AbstractRoutingDataSource实现determineCurrentLookupKey方法,该方法可以实现数据库的动态切换,如下:

public class DynamicDataSource extends AbstractRoutingDataSource {
@Override
protected Object determineCurrentLookupKey() {
return DataSourceContextHolder.getDataSourceType();
}
}

3.定义一个可以设置当前线程的变量的工具类,用于设置对应的数据源名称:

public class DataSourceContextHolder {
private static final ThreadLocal<String> contextHolder = new ThreadLocal<String>();
/**
* @Description: 设置数据源类型
* @param dataSourceType 数据库类型
* @return void
* @throws
*/
public static void setDataSourceType(String dataSourceType) {
contextHolder.set(dataSourceType);
}

/**
* @Description: 获取数据源类型
* @param
* @return String
* @throws
*/
public static String getDataSourceType() {
return contextHolder.get();
}

/**
* @Description: 清除数据源类型
* @param
* @return void
* @throws
*/
public static void clearDataSourceType() {
contextHolder.remove();
}
}

然后在spring中配置,如下:

<!-- 编写spring 配置文件的配置多数源映射关系 -->
<bean class="com.sino.access.database.DynamicDataSource" id="dataSource">
<property name="targetDataSources">
<map key-type="java.lang.String">
<entry value-ref="testDataSource1" key="<span style="font-family: Arial, Helvetica, sans-serif;">testDataSource1</span><span style="font-family: Arial, Helvetica, sans-serif;">"></entry></span>
<entry value-ref="testDataSource2" key="testDataSource2"></entry>
</map>
</property>
<property name="defaultTargetDataSource" ref="testDataSource1">
</property>
</bean>

这样配置两个数据源对应的key分别为testDataSource1和testDataSource2,默认数据库是testDataSource。
4.完成以上步骤后,如果没有数据库的事务管理,已经可以实现数据库的动态切换了。但是如果涉及到数据库的事务管理,需要在数据库事务开启切换数据库,

否则数据库的切换只能在下次数据库操作时才生效。可以定义一个aop处理类在数据库事务开启之前切换数据库,如下:

public class DataSourceAspect implements MethodBeforeAdvice,AfterReturningAdvice
{

@Override
public void afterReturning(Object returnValue, Method method,
Object[] args, Object target) throws Throwable {
// TODO Auto-generated method stub
DataSourceContextHolder.clearDataSourceType();
}

@Override
public void before(Method method, Object[] args, Object target)
throws Throwable {

if (method.isAnnotationPresent(DataSource.class))
{
DataSource datasource = method.getAnnotation(DataSource.class);
DataSourceContextHolder.setDataSourceType(datasource.name());
}
else
{
DataSourceContextHolder.setDataSourceType(SinoConstant.DataSourceType.unityDataSource.toString());
}

}
}

5.设置数据库事务切面和切换数据库切面执行的顺序,如下:

<aop:config>
<aop:pointcut id="transactionPointCut" expression="execution(* com.test.service.*.*(..))" />
<aop:advisor pointcut-ref="transactionPointCut"
advice-ref="txAdvice" order="2" />
<aop:advisor advice-ref="dataSourceExchange" pointcut-ref="transactionPointCut" order="1"/>
</aop:config>

利用aop的order属性设置执行的顺序,这样实现了带事务管理的spring数据库动态切换。

转载于:https://www.cnblogs.com/austinspark-jessylu/p/7676190.html

Spring 配置多个数据源,并实现动态切换相关推荐

  1. springmvc 配置多个数据源,并动态切换

    前言:工作中经常会有两个数据源的情况,所以记录一下.这里测试两个数据源,给出流程和代码. 首先:配置两个数据源 <description>配置mybatis数据源</descript ...

  2. druid 多数据源_Spring Boot + Mybatis 中 配置Druid多数据源并实现自由切换

    概述 前面我们已经介绍过了对MyBatis.Druid的整合,接下来我们在之前的基础上做扩展,实现对Druid多数据源的配置以及动态切换数据源. 问题:多数据源使用场景有哪些呢? 回答:在业务发展中, ...

  3. mybatis手动切换数据库_在Spring项目中使用 Mybatis 如何实现动态切换数据源

    在Spring项目中使用 Mybatis 如何实现动态切换数据源 发布时间:2020-11-17 16:20:11 来源:亿速云 阅读:108 作者:Leah 这篇文章将为大家详细讲解有关在Sprin ...

  4. Springboot 从数据库读取数据库配置信息,动态切换多数据源 最详细实战教程

    以前写过一篇教程,Springboot AOP方式切换多数据源(主从两库类似情况使用最佳): https://blog.csdn.net/qq_35387940/article/details/100 ...

  5. Spring+Mybatis多数据源配置(四)——AbstractRoutingDataSource实现数据源动态切换

    欢迎支持笔者新作:<深入理解Kafka:核心设计与实践原理>和<RabbitMQ实战指南>,同时欢迎关注笔者的微信公众号:朱小厮的博客. 欢迎跳转到本文的原文链接:https: ...

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

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

  7. Spring多数据源配置以及动态切换实现

    Spring多数据源配置以及动态切换实现 问题描述 一:首先是配置数据源 1.使用xml的bean节点来配置 2.使用yml配置+java代码实现配置 二:动态数据源 三:使用AOP切面实现动态数据源 ...

  8. Proxool配置多数据源动态切换

    2019独角兽企业重金招聘Python工程师标准>>> 前段时间遇到多数据源动态切换问题,总结一下,做个记录,以备后续之需! 首先附上proxool连接池的配置方法:http://3 ...

  9. spring boot 切换 oracle 和 mysql_spring-boot多数据源动态切换

    作者:码农教程 出自:码农教程 原文:manongjc.com/detail/14-ucsldoihyzmwcui.html 当项目中存在多数据源时,就涉及到数据源的动态切换,通过研究,特此记录一下. ...

最新文章

  1. js高级程序设计(六)面向对象
  2. Tech UP——EGO北京分会成立啦
  3. 教你如何搭建虚拟专用网连接 OPEN***
  4. OO实现ALV TABLE 十:ALV的页眉页脚
  5. python将html存为pdf_使用Python将HTML转成PDF
  6. 快速web app之道
  7. Ubuntu下部署zabbix 开源监控系统
  8. html5 mp4转换ogv格式,怎么将MP4转换为OGV?这么做超简单!
  9. 鸿蒙20支持哪些设备,华为鸿蒙OS 2.0支持哪些机型,有哪些区别
  10. WEB API异常处理
  11. t450加固态硬盘教程_Thinkpad T450 超级笔记本 开箱更换SSD和内存
  12. 两个栈实现一个队列以及两个队列实现一个栈(Java)
  13. 班长投票小程序的java代码
  14. bom event周期_BOM-event事件
  15. 【历史上的今天】5 月 17 日:面向对象编程之父出生;国内全面接入互联网;惠普收购 Cray
  16. 求解函数最值的几种算法,梯度下降法python实现
  17. 【Origin】Origin准确标注某点
  18. 解决androidstudio unable to delete directory的办法
  19. Brain:一种用于阿尔兹海默症(AD)分类的可解释的深度学习框架
  20. C# LINQ源码分析之ToList()

热门文章

  1. 第14课 跳绳达人 《小学生C++趣味编程》
  2. Python一直报错:SyntaxError: invalid syntax 的原因及解决办法
  3. php把时间戳转换成多少时间之前函数
  4. MATLAB中如何让分度值小点,实验6 干涉的matlab模拟.doc
  5. 服务器 centos 系统漏洞快速修复简易方法
  6. Java工作笔记-Spring Boot上传图片并显示
  7. Qt工作笔记-QMap的进一步操作
  8. Java高级语法笔记-文件操作-链表的存储
  9. Qt creator5.7 OpenCV249之均值滤波(含源码下载)
  10. linux调用函数和case,Shell篇(3)-单双引号 ,函数及case语句用法