多数据源管理:掌握@DS注解的威力 | 京东云技术团队
大家在日常后端开发过程,不可避免的会接触到需要用到配置多个数据源的场景,在这里,小编介绍一种简单方便的,只需要简单的配置和一个@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 } }
1、底层实现原理
底层实现核心类是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的思想,后续小编将写一篇基于AOP的实现方式,欢迎大家关注。
作者:京东保险 郭盼
来源:京东云开发者社区 转载请注明来源
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
9张图深入剖析ConcurrentHashMap
前言 在日常的开发中,我们经常使用key-value键值对的HashMap,其使用哈希表实现,用空间换取时间,提升查询性能 但在多线程的并发场景中,HashMap并不是线程安全的 如果想使用线程安全的,可以使用ConcurrentHashMap、HashTable、Collections.synchronizedMap等 但由于后面二者使用synchronized的粒度太大,因此一般不使用,而使用并发包中的ConcurrentHashMap 在ConcurrentHashMap中,使用volatile保证内存可见性,使得读场景下不需要“加锁”保证原子性 在写场景下使用CAS+synchronized,synchronized只锁哈希表某个索引位置上的首节点,相当于细粒度加锁,增大并发性能 本篇文章将从ConcurrentHashMap的使用,读、写、扩容的实现原理,设计思想等方面进行剖析 查看本文前需要了解哈希表、volatile、CAS、synchronized等知识 volatile可以查看这篇文章:5个案例和流程图让你从0到1搞懂volatile关键字 CAS、synchroni...
- 下一篇
MySQL innoDB 间隙锁产生的死锁问题 | 京东云技术团队
背景 线上经常偶发死锁问题,当时处理一张表,也没有联表处理,但是有两个mq入口,并且消息体存在一样的情况,频率还不是很低,这么一个背景,我非常容易怀疑到,两个消息同时近到这一个事务里面导致的,但是是偶发的,又模拟不出来什么场景会导致死锁,只能进行代码分析,问题还原的方式去排查问题。 业务代码简化成下面 begin update test set yn = 0 where dm_code = "3"; SELECT * from test where dm_code = '3' INSERT INTO demand_flow_followers (dm_code, erp ) values ('3', 'a') , ('3', 'b') , ('3', 'c') 也就是说先update ,select , insert 这么一个顺序 表中存在dm_code ,erp 唯一索引如果不存在索引 第一行update 会导致行锁升级为表锁,反而不会导致问题出现,但是并发太差 结论 先说结论: session1 session2 开启事务 update 开...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- Windows10,CentOS7,CentOS8安装Nodejs环境
- MySQL8.0.19开启GTID主从同步CentOS8
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- Windows10,CentOS7,CentOS8安装MongoDB4.0.16
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- CentOS7,8上快速安装Gitea,搭建Git服务器
- CentOS6,CentOS7官方镜像安装Oracle11G
- SpringBoot2全家桶,快速入门学习开发网站教程
- SpringBoot2更换Tomcat为Jetty,小型站点的福音
- CentOS7安装Docker,走上虚拟化容器引擎之路