⭐⭐⭐ Spring Boot 项目实战 ⭐⭐⭐ Spring Cloud 项目实战
《Dubbo 实现原理与源码解析 —— 精品合集》 《Netty 实现原理与源码解析 —— 精品合集》
《Spring 实现原理与源码解析 —— 精品合集》 《MyBatis 实现原理与源码解析 —— 精品合集》
《Spring MVC 实现原理与源码解析 —— 精品合集》 《数据库实体设计合集》
《Spring Boot 实现原理与源码解析 —— 精品合集》 《Java 面试题 + Java 学习指南》

摘要: 原创出处 blog.csdn.net/jdcdev_/article/details/133635988 「郭盼/京东云开发者社区」欢迎转载,保留摘要,谢谢!


🙂🙂🙂关注微信公众号:【芋道源码】有福利:

  1. RocketMQ / MyCAT / Sharding-JDBC 所有源码分析文章列表
  2. RocketMQ / MyCAT / Sharding-JDBC 中文注释源码 GitHub 地址
  3. 您对于源码的疑问每条留言都将得到认真回复。甚至不知道如何读源码也可以请教噢。
  4. 新的源码解析文章实时收到通知。每周更新一篇左右。
  5. 认真的源码交流微信群。

大家在日常后端开发过程,不可避免的会接触到需要用到配置多个数据源的场景,在这里,小编介绍一种简单方便的,只需要简单的配置和一个 @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
}
}

2、底层实现原理

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

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

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

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

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

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

3、总结

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

文章目录
  1. 1. 1、配置方式
  2. 2. 2、底层实现原理
  3. 3. 3、总结