热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

java动态数据源_微服务框架和应用框架实现多数据源、动态数据源切换

本项目使用SpringBoot和MyBatis实现多数据源,动态数据源的切换;有多种不同的实现方式,在学习的过程中发现没有文章将这些方式和

本项目使用 Spring Boot 和 MyBatis 实现多数据源,动态数据源的切换;有多种不同的实现方式,在学习的过程中发现没有文章将这些方式和常见的问题集中处理,所以将常用的方式和常见的问题都写在了在本项目的不同分支上:

master: 使用了多数据源的 RESTful API 接口,使用 Druid 实现了 DAO 层数据源动态切换和只读数据源负载均衡dev: 最简单的切面和注解方式实现的动态数据源切换druid: 通过切面和注解方式实现的使用 Druid 连接池的动态数据源切换aspect_dao: 通过切面实现的 DAO 层的动态数据源切换roundrobin: 通过切面使用轮询方式实现的只读数据源负载均衡以上分支都是基于 dev 分支修改或扩充而来,基本涵盖了常用的多数据源动态切换的方式,基本的原理都一样,都是通过切面根据不同的条件在执行数据库操作前切换数据源

在使用的过程中基本踩遍了所有动态数据源切换的坑,将常见的一些坑和解决方法写在了 Issues 里面

该项目使用了一个可写数据源和多个只读数据源,为了减少数据库压力,使用轮循的方式选择只读数据源;考虑到在一个 Service 中同时会有读和写的操作,所以本应用使用 AOP 切面通过 DAO 层的方法名切换只读数据源;但这种方式要求数据源主从一致,并且应当避免在同一个 Service 方法中写入后立即查询,如果必须在执行写入操作后立即读取,应当在 Service 方法上添加 @Transactional 注解以保证使用主数据源

需要注意的是,使用 DAO 层切面后不应该在 Service 类层面上加 @Transactional 注解,而应该添加在方法上,这也是 Spring 推荐的做法

动态切换数据源依赖 configuration 包下的4个类来实现,分别是:DataSourceRoutingDataSource.javaDataSourceConfigurer.javaDynamicDataSourceContextHolder.javaDynamicDataSourceAspect.java

添加依赖

ed2b94fd5303db5c062f276b3939dff9.png

.

创建数据库及表

分别创建数据库product_master,product_slave_alpha,product_slave_beta,product_slave_gamma在以上数据库中分别创建表product,并插入不同数据

32846647903058db10170e150db08925.png

.

.

配置数据源

application.properties

f4a2824cb996a6396f1d90788d6ae26e.png

.

cc6815495b093c16ae2d979e3c051030.png

.

343930e071b4569d28c360a00eda79fe.png

.

配置数据源

DataSourceKey.java

6774b6c5cdd8c39bcaba2d38a23cb603.png

.

DataSourceRoutingDataSource.java该类继承自AbstractRoutingDataSource类,在访问数据库时会调用该类的determineCurrentLookupKey()方法获取数据库实例的 key

6eac42d5a9b80d3c61c48ba04d21e21a.png

.

DataSourceConfigurer.java数据源配置类,在该类中生成多个数据源实例并将其注入到ApplicationContext中

bbbe866f70bca880b5ebf18360b28841.png

.

d0f0dbcbd2e2b0cd46bffad9cb43dc26.png

.

0cf1213c905b4c0be3b4ff66d60204a4.png

.

759f6ec4beee987a4af61b97f24b9ba2.png

.

DynamicDataSourceContextHolder.java该类为数据源上下文配置,用于切换数据源

92508327ce7e48dde30beefe464e4d76.png

.

1bda1e252b0c923430557ed22417e3be.png

.

4043101c054a785ec579fdca69e51cdc.png

.

0acb7bd535b14adadf02001da027adf2.png

.

DynamicDataSourceAspect.java动态数据源切换的切面,切 DAO 层,通过 DAO 层方法名判断使用哪个数据源,实现数据源切换关于切面的 Order 可以可以不设,因为 @Transactional 是最低的,取决于其他切面的设置,并且在 org.springframework.core.annotation.AnnotationAwareOrderComparator 会重新排序

644a8117bc22eecb442c631472c6e8ce.png

.

3821f465361692ec8f9e68566b29ad74.png

.

配置 Product REST API 接口

ProductController.java

cbf97ed0966c56fa1496dcb7b037b387.png

.

64266185c16d6997c70e1ee67b52d77e.png

.

ProductService.java

1aad1615b807a96a26f65fcdb31efe4d.png

.

2abe96576e418eeb29574203287b52f3.png

.

ProductDao.java

a14ebc4145b7c9f0437569d69628fbbb.png

.

ProductMapper.xml启动项目,此时访问 /product/1 会返回 product_master 数据库中 product 表中的所有数据,多次访问 /product 会分别返回 product_slave_alpha、product_slave_beta、product_slave_gamma 数据库中 product 表中的数据,同时也可以在看到切换数据源的 log,说明动态切换数据源是有效的

注意

在该应用中因为使用了 DAO 层的切面切换数据源,所以 @Transactional 注解不能加在类上,只能用于方法;有 @Trasactional注解的方法无法切换数据源

.



推荐阅读
author-avatar
张光和尚山秀珍
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有