Mybatis-Plus中使用@DS注解动态选择数据源的源码解读

 更新时间:2023年07月31日 10:29:13   作者:labulaka24  
这篇文章主要介绍了Mybatis-Plus中使用@DS注解动态选择数据源的源码解读,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

一、使用场景

1、首先在yml文件中配置多个数据源

2、根据注解的Target可以知道

可以在我们对应的类上、方法上使用@DS注解(一般是用在mapper、service),使用过该注解的方法即可操作到对应的数据源

二、原理剖析(为什么使用过该注解的方法即可操作到对应的数据源)

1、对应源码所在包的位置

2、首先mybatis-plus使用

com.baomidou.dynamic.datasource.AbstractRoutingDataSource继承 AbstractDataSource接管数据源;

具体实现类(ctrl+alt+b可以查看抽象类或者的具体实现类)为com.baomidou.dynamic.datasource.DynamicRoutingDataSource。

项目初始化调用public synchronized void addDataSource(String ds, DataSource dataSource)加载数据源,数据源存进dataSourceMap中。

AbstracRoutingDataSource

DynamicRoutingDataSource

3、当我们发送具体的操作请求的时候

进行数据操作时,方法会被com.baomidou.dynamic.datasource.aop.DynamicDataSourceAnnotationInterceptor拦截

 DynamicDataSourceAnnotationInterceptor

 拦截器首先从被拦截的方法或者类(一般@DS注解用于Service,也可用于Mapper和Controller)上寻找@DS注解,获取到@DS注解的值后将其存入

com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder;

DynamicDataSourceContextHolder使用ThreadLocal存储当前线程的数据源名。

 3、进行数据操作时

会调用org.springframework.jdbc.datasource.getConnection()方法;

getConnection()方法最终调用了com.baomidou.dynamic.datasource.AbstractRoutingDataSource的getConnection()方法;

 跟进方法我们可以看到determineDataSource()由子类com.baomidou.dynamic.datasource.DynamicRoutingDataSource实现,可以看到DynamicRoutingDataSource从DynamicDataSourceContextHolder获取数据源名称,这个在之前拦截器处理存进ThreadLocal中,如果有数据源名称则从dataSourceMap中获取,没有则获取默认的primary数据源。

 此时的datasource已经切换成了我们需要的数据源

 4、数据操作完成后

方法返回第二步中的拦截器,执行DynamicDataSourceContextHolder.poll();清除掉此次Threadlocal中的数据源,避免影响后续数据操作。

特别注意:

不可在事务中切换数据库,保证事务需要方法使用同一连接,使用@DS(dataSourceOne)方法调用@DS(dataSourceTwo)无法切换连接,会导致方法报错。

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。 

相关文章

  • java中匿名内部类详解

    java中匿名内部类详解

    这篇文章主要对java中的匿名内部类的详细总结,需要的朋友可以参考下
    2017-04-04
  • springboot+thymeleaf+mybatis实现甘特图的详细过程

    springboot+thymeleaf+mybatis实现甘特图的详细过程

    这篇文章主要介绍了springboot+thymeleaf+mybatis实现甘特图的详细过程,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-07-07
  • 详解IDEA社区版(Community)和付费版(UItimate)的区别

    详解IDEA社区版(Community)和付费版(UItimate)的区别

    这篇文章主要介绍了详解IDEA社区版(Community)和付费版(UItimate)的区别,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-11-11
  • RabbitMq报错reply-code=406 reply-text=PRECONDITION_FAILED解决

    RabbitMq报错reply-code=406 reply-text=PRECONDITION_FAILED

    这篇文章主要为大家介绍了RabbitMq报错reply-code=406 reply-text=PRECONDITION_FAILED分析解决,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-12-12
  • Java 集合去重的三种方法

    Java 集合去重的三种方法

    本主要介绍了Java 集合去重的三种方法,包含HashSet,Stream API和手动遍历并使用Map三种,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2024-07-07
  • jdk中keytool的使用以及如何提取jks文件中的公钥和私钥

    jdk中keytool的使用以及如何提取jks文件中的公钥和私钥

    JKS文件由公钥和密钥构成利用Java Keytool工具生成的文件,它是由公钥和密钥构成的,下面这篇文章主要给大家介绍了关于jdk中keytool的使用以及如何提取jks文件中公钥和私钥的相关资料,需要的朋友可以参考下
    2024-03-03
  • Java基础强化训练输入错误即结束进程

    Java基础强化训练输入错误即结束进程

    本文主要介绍了Java编程的基础知识强化应用,文中实例涉及到了许多基础知识,new对象,控制台输入,if语句等。很实用,需要的朋友可以参考下
    2017-09-09
  • 一篇文章看懂Java异常处理

    一篇文章看懂Java异常处理

    异常是程序中的一些错误,但并不是所有的错误都是异常,并且错误有时候是可以避免的,这篇文章主要给大家介绍了关于Java异常处理的相关资料,需要的朋友可以参考下
    2021-11-11
  • 在mybatis中去除多余的前缀或者后缀操作

    在mybatis中去除多余的前缀或者后缀操作

    这篇文章主要介绍了在mybatis中去除多余的前缀或者后缀操作。具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-11-11
  • JavaWeb中的Response常用方法解析

    JavaWeb中的Response常用方法解析

    这篇文章主要介绍了JavaWeb中的Response常用方法解析,response对象是用来对客户端进行响应的当浏览器发出请求时, Web容器创建一个ServletRequest对象封装请求信息,一个ServletResponse对象封装响应信息,对象作为Servlet的service()方法中的参数,需要的朋友可以参考下
    2023-11-11

最新评论