项目中将一个库的某些标的某些数据保存到另一个库。

使用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多数据库切换,(动态数据源)。的更多相关文章

  1. 小D课堂-SpringBoot 2.x微信支付在线教育网站项目实战_3-1.整合Mybatis访问数据库和阿里巴巴数据源

    笔记 1.整合Mybatis访问数据库和阿里巴巴数据源     简介:整合mysql 加入mybatis依赖,和加入alibaba druid数据源 1.加入依赖(可以用 http://start.s ...

  2. mybatis用spring的动态数据源实现读写分离

    一.环境: 三个mysql数据库.一个master,两个slaver.master写数据,slaver读数据. 二.原理: 借助Spring的 AbstractRoutingDataSource 这个 ...

  3. Spring Boot + Mybatis + Druid 动态切换多数据源

    在大型应用程序中,配置主从数据库并使用读写分离是常见的设计模式. 在Spring应用程序中,要实现读写分离,最好不要对现有代码进行改动,而是在底层透明地支持. 这样,就需要我们再一个项目中,配置两个, ...

  4. SpringBoot+Mybatis 实现动态数据源切换方案

    背景 最近让我做一个大数据的系统,分析了一下,麻烦的地方就是多数据源切换抽取数据.考虑到可以跨服务器跨数据库抽数,再整理数据,就配置了这个动态数据源的解决方案.在此分享给大家. 实现方案 数据库配置文 ...

  5. Spring主从数据库的配置和动态数据源切换原理

    原文:https://www.liaoxuefeng.com/article/00151054582348974482c20f7d8431ead5bc32b30354705000 在大型应用程序中,配 ...

  6. Spring-Boot 多数据源配置+动态数据源切换+多数据源事物配置实现主从数据库存储分离

    一.基础介绍 多数据源字面意思,比如说二个数据库,甚至不同类型的数据库.在用SpringBoot开发项目时,随着业务量的扩大,我们通常会进行数据库拆分或是引入其他数据库,从而我们需要配置多个数据源. ...

  7. 如何通过Spring Boot配置动态数据源访问多个数据库

    之前写过一篇博客<Spring+Mybatis+Mysql搭建分布式数据库访问框架>描述如何通过Spring+Mybatis配置动态数据源访问多个数据库.但是之前的方案有一些限制(原博客中 ...

  8. Spring动态切换多数据源解决方案

    Spring动态配置多数据源,即在大型应用中对数据进行切分,并且采用多个数据库实例进行管理,这样可以有效提高系统的水平伸缩性.而这样的方案就会不同于常见的单一数据实例的方案,这就要程序在运行时根据当时 ...

  9. AbstractRoutingDataSource实现动态数据源切换 专题

    需求:系统中要实现切换数据库(业务数据库和his数据库) 网上很多资料上有提到AbstractRoutingDataSource,大致是这么说的 在Spring 2.0.1中引入了AbstractRo ...

随机推荐

  1. Math 类

    Math 类 java.lang.Object java.lang.Math 方法签名 public final class Math extends Object public static fin ...

  2. Navicat 12.1激活

    去官网下载 https://www.navicat.com.cn/download/navicat-premium 然后下载这个破解包 第一个是整合了 navicat121_premium_cs_x6 ...

  3. [Linux] 树莓派 4B 安装 Ubuntu 19.10 (Eoan Ermine) IOT 版

    硬件:Raspberry Pi 4B系统:Ubuntu 19.10 (Eoan Ermine) for IOT官网:https://ubuntu.com/download/iot/raspberry- ...

  4. Spring 学习指南 第三章 bean的配置 (未完结)

    第三章 bean 的配置 ​ 在本章中,我们将介绍以下内容: bean 定义的继承: 如何解决 bean 类的构造函数的参数: 如何配置原始类型 (如 int .float 等) .集合类型(如 ja ...

  5. 【LeetCode】 #7:反转整数 C语言

    目录 题目 思路 初步想法 进一步想法 总结 最近打算练习写代码的能力,所以从简单题开始做. 大部分还是用C语言来解决. @(解法) 题目 给出一个 32 位的有符号整数,你需要将这个整数中每位上的数 ...

  6. jenkins+springboot+maven多模块部署

    一.jenkins的安装配置 1.去官网下载war包,这种方式比较简单方便 java -jar jenkins.war --httpPort=49001 2.首次运行有一个key放在服务器上需要你填入 ...

  7. Html 对象的常用事件列举

    事件名称 触发时间 对象例举 OnBlur 对象失去输入焦点 窗口和所有的表单对象 OnChange 用户改变对象的值 文本框.文本区域.选择列表等 OnClick 用户鼠标点击 链接.按钮.单选钮. ...

  8. 唯一ID生成器--雪花算法

    在微服务架构,分布式系统中的操作会有一些全局性ID的需求,所以我们不能用数据库本身的自增功能来产生主键值,只能由程序来生成唯一的主键值.我们采用的是twitter的snokeflake(雪花)算法. ...

  9. GoLang基础数据类型---字典

    Map 是 Go 中的内置类型,它将键与值绑定到一起.可以通过键获取相应的值. 如何创建 map? 可以通过将键和值的类型传递给内置函数 make 来创建一个 map.语法为:make(map[Key ...

  10. gin-swagger生成API文档

    github地址:https://github.com/swaggo/gin-swagger 下载安装cmd/swag命令工具包 先下载cmd包,才能执行相关命令 go get -u github.c ...