【SpringBoot DB 系列】Mybatis 基于 AbstractRoutingDataSource 与 AOP 实现多数据源切换
前面一篇博文介绍了 Mybatis 多数据源的配置,简单来讲就是一个数据源一个配置指定,不同数据源的 Mapper 分开指定;本文将介绍另外一种方式,借助AbstractRoutingDataSource
来实现动态切换数据源,并通过自定义注解方式 + AOP 来实现数据源的指定
I. 环境准备
1. 数据库相关
以 mysql 为例进行演示说明,因为需要多数据源,一个最简单的 case 就是一个物理库上多个逻辑库,本文是基于本机的 mysql 进行操作
创建数据库test
与 story
,两个库下都存在一个表money
(同名同结构表,但是数据不同哦)
1 | sql复制代码CREATE TABLE `money` ( |
2. 项目环境
本项目借助SpringBoot 2.2.1.RELEASE
+ maven 3.5.3
+ IDEA
进行开发
下面是核心的pom.xml
(源码可以再文末获取)
1 | xml复制代码<dependencies> |
配置文件信息application.yml
1 | yaml复制代码# 数据库相关配置,请注意这个配置和之前一篇博文的不一致,后面会给出原因 |
II. 多数据源配置
强烈建议没有看上一篇博文的小伙伴,先看一下上篇博文 【DB 系列】Mybatis 多数据源配置与使用
在开始之前,先有必要回顾一下之前 Mybatis 多数据源配置的主要问题在哪里
- 多加一个数据源,需要多一份配置
- Mapper 文件需要分包处理,对开发人员而言这是个潜在的坑
针对上面这个,那我们想实现的目的也很清晰了,解决上面两个问题
1. AbstractRoutingDataSource
实现多数据源的关键,从名字上就可以看出,它就是用来路由具体的数据源的,其核心代码如
1 | java复制代码// 返回选中的数据源 |
其中determineCurrentLookupKey
需要我们自己来实现,到底返回哪个数据源
2. 动态数据源实现
我们创建一个DynamicDataSource
继承自上面的抽象类
1 | java复制代码public class DynamicDataSource extends AbstractRoutingDataSource { |
注意上面的实现方法,怎样决定具体的返回数据源呢?
一个可考虑的方法是,在 Mapper 文件上添加一个注解@DS
,里面指定对应的数据源,然后再执行时,通过它来确定具体需要执行的数据源;
因为上面的实现没有传参,因此我们考虑借助线程上下文的方式来传递信息
1 | java复制代码public class DSTypeContainer { |
3. 注解实现
上面虽然给出了数据源选择的策略,从线程上下文中获取DataBaseType
,但是应该怎样向线程上下文中塞这个数据呢?
我们需要支持的方案必然是在 Sql 执行之前,先拦截它,写入这个DataBaseType
,因此我们可以考虑在xxxMapper
接口上,定义一个注解,然后拦截它的访问执行,在执行之前获取注解中指定的数据源写入上下文,在执行之后清楚上下文
一个最基础的数据源注解@DS
1 | java复制代码@Target(ElementType.TYPE) |
注解拦截
1 | java复制代码@Aspect |
4. 注册配置
接下来就是比较关键的数据源配置了,我们现在需要注册DynamicDataSource
,然后将他提供给SqlSessionFactory
,在这里,我们希望解决即便多加数据源也不需要修改配置,所以我们调整了一下数据源的配置结构
1 | yaml复制代码spring: |
然后给出一个加载上面配置的配置类DSProperties
1 | java复制代码@Data |
然后我们的AutoConfiguration
类的实现方式就相对明确了(建议对比上一篇博文中的配置类)
1 | java复制代码@Configuration |
5. 数据库实体类
项目结构图
所有前面的东西属于通用配置相关,接下来给出具体的数据库操作相关实体类、Mapper 类
数据库实体类StoryMoneyEntity
1 | java复制代码@Data |
mapper 定义接口 StoryMoneyMapper
+ TestMoneyMapper
1 | java复制代码@DS(value = "story") |
对应的 xml 文件
1 | xml复制代码<?xml version="1.0" encoding="UTF-8"?> |
数据库操作封装类StoryMoneyRepository
+ TestMoneyRepository
1 | java复制代码@Repository |
6. 测试
最后简单的测试下,动态数据源切换是否生效
1 | java复制代码@SpringBootApplication |
输出日志如下
6.小结
本文主要给出了一种基于AbstractRoutingDataSource
+ AOP
实现动态数据源切换的实现方式,使用了下面三个知识点
AbstractRoutingDataSource
实现动态数据源切换- 自定义
@DS
注解 + AOP 指定 Mapper 对应的数据源 ConfigurationProperties
方式支持添加数据源无需修改配置
II. 其他
0. 项目
相关博文
- 【DB 系列】Mybatis 多数据源配置与使用
- 【DB 系列】JdbcTemplate 之多数据源配置与使用
- 【DB 系列】Mybatis-Plus 代码自动生成
- 【DB 系列】MybatisPlus 整合篇
- 【DB 系列】Mybatis+注解整合篇
- 【DB 系列】Mybatis+xml 整合篇
源码
1. 一灰灰 Blog
尽信书则不如,以上内容,纯属一家之言,因个人能力有限,难免有疏漏和错误之处,如发现 bug 或者有更好的建议,欢迎批评指正,不吝感激
下面一灰灰的个人博客,记录所有学习和工作中的博文,欢迎大家前去逛逛
- 一灰灰 Blog 个人博客 blog.hhui.top
- 一灰灰 Blog-Spring 专题博客 spring.hhui.top
- 微信公众号: 一灰灰blog
本文转载自: 掘金