mybatis多数据库切换,(动态数据源)。
项目中将一个库的某些标的某些数据保存到另一个库。
使用spring的aop编程动态切换数据源,代码如下,以备下次用到!
1.先将两个数据库连接,创建两个数据源,交于spring管理!
<bean id="dataSource"
class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
<property name="driverClassName" value="${jdbc.driver}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.user}" />
<property name="password" value="${jdbc.password}" />
</bean> <bean id="dataSource2"
class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
<property name="driverClassName" value="${jdbc.driver}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.user}" />
<property name="password" value="${jdbc.password}" />
</bean>
2.将动态切换数据源的类交给spring
<bean id="dynamicDataSource" class="cn.**.**.common.db.DynamicDataSource">
<property name="targetDataSources">
<map key-type="java.lang.String">
<!-- 指定lookupKey和与之对应的数据源 -->
<entry key="dataSource" value-ref="dataSource"></entry>
<entry key="dataSource2" value-ref="dataSource2"></entry>
</map>
</property>
<!-- 这里可以指定默认的数据源 -->
<property name="defaultTargetDataSource" ref="dataSource" />
</bean>
3.创建数据源切换的类,必须继承 AbstractRoutingDataSource 这个类(数据源动态切换必须继承该类)
public class DynamicDataSource extends AbstractRoutingDataSource { @Override
protected Object determineCurrentLookupKey() {
// 从自定义的位置获取数据源标识
return DynamicDataSourceHolder.getDataSource();
} }
4.将数据源放进线程中,避免相互干扰
public class DynamicDataSourceHolder { /**
* 注意:数据源标识保存在线程变量中,避免多线程操作数据源时互相干扰
*/
private static final ThreadLocal<String> THREAD_DATA_SOURCE = new ThreadLocal<String>(); public static String getDataSource() {
String dataSource = THREAD_DATA_SOURCE.get();
if(StringUtils.isEmpty(dataSource)){
return DataSourceKey.DATA_SOURCE;
}else{
return dataSource;
}
} public static void setDataSource(String dataSource) {
THREAD_DATA_SOURCE.set(dataSource);
} public static void clearDataSource() {
THREAD_DATA_SOURCE.remove();
} }
5.数据源的key
DataSourceKey 这个类是多个数据源在spring管理中的name标识,可通过key取得数据源。
6.设置默认的数据源。
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DataSource { /**
* 默认是某个数据源
*/
String value() default DataSourceKey.DATA_SOURCE; }
7.根据spring的aop在执行之前将数据源放进线程中,动态切换数据源。
@Aspect
@Component
@Order(0)
public class DataSourceAspect{ private Logger logger = Logger.getLogger(getClass()); @Pointcut("execution(public * cn.**.**.service..*Service.*(..))")
public void dataSourceAspect(){}; /**
* 拦截目标方法,获取由@DataSource指定的数据源标识,设置到线程存储中以便切换数据源
*/
@Before("dataSourceAspect()")
public void before(JoinPoint point) throws Exception{
Class<?> target = point.getTarget().getClass();
MethodSignature signature = (MethodSignature) point.getSignature();
// 默认使用目标类型的注解,如果没有则使用其实现接口的注解
for (Class<?> clazz : target.getInterfaces()) {
resolveDataSource(clazz, signature.getMethod());
}
resolveDataSource(target, signature.getMethod());
} private void resolveDataSource(Class<?> clazz, Method method) {
try {
Class<?>[] types = method.getParameterTypes();
// 先使用类型注解
if (clazz.isAnnotationPresent(DataSource.class)) {
DataSource source = clazz.getAnnotation(DataSource.class);
DynamicDataSourceHolder.setDataSource(source.value());
}else{
DynamicDataSourceHolder.clearDataSource();
}
// 方法注解可以覆盖类型注解
Method m = clazz.getMethod(method.getName(), types);
if (m != null && m.isAnnotationPresent(DataSource.class)) {
DataSource source = m.getAnnotation(DataSource.class);
DynamicDataSourceHolder.setDataSource(source.value());
}
logger.info("选择连接加载的DB :"+DynamicDataSourceHolder.getDataSource());
} catch (Exception e) {
//如果出现异常不能断了所有连接,默认还是某个数据库连接
logger.error("选择连接加载DB ERROR "+clazz+":" +e.getMessage());
}
}
}
8.service层动态切换
默认的数据源不用标明,另一个数据源用@DataSource(DataSourceKey.LYD_DATA_SOURCE) 在service上标明即可。
9.另一个库的查询也可用@Results注解封装返回的实体(或map),sql用@Select注解
10.在多数据源切换中,不要在一个事务方法里面用到两个数据源,不然会切换不过去。因为事务一般定义在service层,所以如果用到两个数据源,可以将两个数据源放在controller进行。
mybatis多数据库切换,(动态数据源)。的更多相关文章
- 小D课堂-SpringBoot 2.x微信支付在线教育网站项目实战_3-1.整合Mybatis访问数据库和阿里巴巴数据源
笔记 1.整合Mybatis访问数据库和阿里巴巴数据源 简介:整合mysql 加入mybatis依赖,和加入alibaba druid数据源 1.加入依赖(可以用 http://start.s ...
- mybatis用spring的动态数据源实现读写分离
一.环境: 三个mysql数据库.一个master,两个slaver.master写数据,slaver读数据. 二.原理: 借助Spring的 AbstractRoutingDataSource 这个 ...
- Spring Boot + Mybatis + Druid 动态切换多数据源
在大型应用程序中,配置主从数据库并使用读写分离是常见的设计模式. 在Spring应用程序中,要实现读写分离,最好不要对现有代码进行改动,而是在底层透明地支持. 这样,就需要我们再一个项目中,配置两个, ...
- SpringBoot+Mybatis 实现动态数据源切换方案
背景 最近让我做一个大数据的系统,分析了一下,麻烦的地方就是多数据源切换抽取数据.考虑到可以跨服务器跨数据库抽数,再整理数据,就配置了这个动态数据源的解决方案.在此分享给大家. 实现方案 数据库配置文 ...
- Spring主从数据库的配置和动态数据源切换原理
原文:https://www.liaoxuefeng.com/article/00151054582348974482c20f7d8431ead5bc32b30354705000 在大型应用程序中,配 ...
- Spring-Boot 多数据源配置+动态数据源切换+多数据源事物配置实现主从数据库存储分离
一.基础介绍 多数据源字面意思,比如说二个数据库,甚至不同类型的数据库.在用SpringBoot开发项目时,随着业务量的扩大,我们通常会进行数据库拆分或是引入其他数据库,从而我们需要配置多个数据源. ...
- 如何通过Spring Boot配置动态数据源访问多个数据库
之前写过一篇博客<Spring+Mybatis+Mysql搭建分布式数据库访问框架>描述如何通过Spring+Mybatis配置动态数据源访问多个数据库.但是之前的方案有一些限制(原博客中 ...
- Spring动态切换多数据源解决方案
Spring动态配置多数据源,即在大型应用中对数据进行切分,并且采用多个数据库实例进行管理,这样可以有效提高系统的水平伸缩性.而这样的方案就会不同于常见的单一数据实例的方案,这就要程序在运行时根据当时 ...
- AbstractRoutingDataSource实现动态数据源切换 专题
需求:系统中要实现切换数据库(业务数据库和his数据库) 网上很多资料上有提到AbstractRoutingDataSource,大致是这么说的 在Spring 2.0.1中引入了AbstractRo ...
随机推荐
- K3Wise插件开发实战教程(全套)持续更新中。。。
这是林枫山自己编写制作的全套K3wise插件教程,欢迎下载学习. 下载目录链接如下(如果链接下载不了,请加QQ:714259796获取教程): 进度01-K3Wise数据表详解 下载学习文档 ...
- Ipinstall软件工具-可视对讲
Ipinstall软件工具操作说明 安居宝Ipinstall软件工具是用于联网型对讲系统中网络设备的属性及参数修改,该设备在系统中是否能正常运行,其属性和参数的设置起着决定性的作用, 然而设备的属性. ...
- .net桌面程序或者控制台程序使用NLog时的注意事项
Nuget添加NLog 添加nlog.config文件,并选择属性->始终复制 不选择始终复制,编译后nlog.config是没有的. 具体使用: private static readonly ...
- XLNet and Robertra
XLNET But the AE language model also has its disadvantages. It uses the [MASK] in the pretra ...
- Ubuntu下安装与卸载opencv模块
opencv安装 因工程需要,想在python中调用opencv import cv2 现在记录一下如何在Linux系统(ubutun)下安装该模块: 参考了一篇博客:http://blog.csdn ...
- 玩转 SpringBoot 2 快速整合 Filter
概述 SpringBoot 中没有 web.xml, 我们无法按照原来的方式在 web.xml 中配置 Filter .但是我们可以通过 JavaConfig(@Configuration +@Bea ...
- Python多进程方式抓取基金网站内容的方法分析
因为进程也不是越多越好,我们计划分3个进程执行.意思就是 :把总共要抓取的28页分成三部分. 怎么分呢? # 初始range r = range(1,29) # 步长 step = 10 myList ...
- golang http及其他标准库
- golang --写test测试用例
安装gotests插件自动生成测试代码: go get -u -v github.com/cweill/gotests/... 如何编写测试用例 由于go test命令只能在一个相应的目录下执行所有文 ...
- WPF 获取元素(Visual)相对于屏幕设备的缩放比例,可用于清晰显示图片
原文:WPF 获取元素(Visual)相对于屏幕设备的缩放比例,可用于清晰显示图片 我们知道,在 WPF 中的坐标单位不是屏幕像素单位,所以如果需要知道某个控件的像素尺寸,以便做一些与屏幕像素尺寸相关 ...