多数据源管理:掌握 @DS 注解的威力

👉 这是一个或许对你有用的社群

🐱 一对一交流/面试小册/简历优化/求职解惑,欢迎加入「芋道快速开发平台」知识星球。下面是星球提供的部分资料: 

63c194c5092760291a67a383b6f86c7a.gif

👉这是一个或许对你有用的开源项目

国产 Star 破 10w+ 的开源项目,前端包括管理后台 + 微信小程序,后端支持单体和微服务架构。

功能涵盖 RBAC 权限、SaaS 多租户、数据权限、商城、支付、工作流、大屏报表、微信公众号等等功能:

  • Boot 地址:https://gitee.com/zhijiantianya/ruoyi-vue-pro

  • Cloud 地址:https://gitee.com/zhijiantianya/yudao-cloud

  • 视频教程:https://doc.iocoder.cn

来源:blog.csdn.net/jdcdev_
/article/details/133635988

b09553f3d729ef0503449bef25843338.jpeg


大家在日常后端开发过程,不可避免的会接触到需要用到配置多个数据源的场景,在这里,小编介绍一种简单方便的,只需要简单的配置和一个 @DS 注解就能实现动态数据源的方式,这种动态数据源底层原理是基于 Mybatis-plus 来实现的。

1、配置方式

首先是 pom.xml。

<dependency>
<groupId>com.baomidou</groupId>
<artifactId>dynamic-datasource-spring-boot-starter</artifactId>
<version>3.4.1</version>
</dependency>

随后配上多数据源,我们的项目中分别配置了 MySQL 和 Doris 两种数据库。

spring:
        datasource:
        druid:
        localdb:
        url: xxx
        username: xxx
        driver-class-name: com.mysql.jdbc.Driver
        type: com.alibaba.druid.pool.DruidDataSource
        doris:
        url: xxx
        username: xxx
        driver-class-name: com.mysql.jdbc.Driver
        type: com.alibaba.druid.pool.DruidDataSource

最后需要使用哪个数据库,在对应的方法上加上对应的 @DS(“数据库名”)注解就可以了,在类上加 @DS(“数据库名”),那么整个类下的所有方法都会使用到这个数据源,实现方式是不是非常简单。

@Service
@DS("localdb")
public class testServiceImpl extends BaseServiceImpl<testMapper, testBean> implements testService {

    public void save(String arg1) {
        //TODO
    }

    public void find(String arg2) {
        //TODO
    }
}

基于 Spring Boot + MyBatis Plus + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能

  • 项目地址:https://github.com/YunaiV/ruoyi-vue-pro

  • 视频教程:https://doc.iocoder.cn/video/

2、底层实现原理

底层实现核心类是 com.baomidou.dynamic.datasource.DynamicRoutingDataSource,继承自 AbstractDataSource。

b2ee4e7762fa6b26c2dafa838c086a11.png a2ba16f28a58dae40d09f151b1f0391c.png

项目在初始化的时候会调用 DynamicRoutingDataSource 里面的 public synchronized void addDataSource(String ds, DataSource dataSource) 方法加载数据源,数据源存进 dataSourceMap 中。

3cc22b9801548948bd8551e62fc3f43c.png

随后,如果进行数据库操作,以方法为最小粒度,执行对应方法时,会被 DynamicDataSourceAnnotationInterceptor 拦截器拦截。

35afa6d745d6ca6c33b319571e30c5f6.png

执行 determineDatasource 方法,扫描加了 @DS 注解的类或者方法,随后调用 DynamicDataSourceContextHolder.poll 方法。

48ccb6b7e2f95b83f2c688db85790695.png

DynamicDataSourceContextHolder.poll 方法将当前线程的数据源名加到对应的 ThreadLocal 线程本地中。

2a360a1a9787ea824a2f91490152fe75.png

在之后的数据操作中,会调用 org.springframework.jdbc.datasource.getConnection() 方法,ThreadLocal 中获取之前拦截器存进去动态数据源名,如果没有获取到,就默认为配置的 primary 数据源,这完成了对应的动态数据源切换。

7e9cd80f24c7c6a77f44289919ec2aa4.png

基于 Spring Cloud Alibaba + Gateway + Nacos + RocketMQ + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能

  • 项目地址:https://github.com/YunaiV/yudao-cloud

  • 视频教程:https://doc.iocoder.cn/video/

3、总结

基于 Mybatis-plus 的 @DS 注解可以实现动态数据源切换,具有实现简单的优点,虽然没有 AOP 实现,但是用到了 AOP 的思想。


欢迎加入我的知识星球,全面提升技术能力。

👉 加入方式,长按”或“扫描”下方二维码噢

75a8a21a85cfc45a5c046f7a369e7b28.png

星球的内容包括:项目实战、面试招聘、源码解析、学习路线。

e78f35f7bd25da741793816088740b25.png

1e1e03a16f5dcc07cd11d6a04ccfbc08.pngc92034de15d736f5ffcb2fef098bc478.png9e55d239c7854939b11ff8124f3cb07d.png7134ff4dcefe86e8c0b65888f9367383.png

文章有帮助的话,在看,转发吧。
谢谢支持哟 (*^__^*)
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值