Spring Boot中实现多数据源连接和切换的方案
Spring Boot中实现多数据源连接和切换的方案
在Spring Boot项目中,随着业务需求的增长,我们往往需要连接多个数据库,即实现多数据源连接和切换。这种需求可能源于数据库的读写分离、微服务架构下的服务拆分、数据分库分表等场景。本文将详细探讨Spring Boot中实现多数据源连接和切换的多种方案,并给出相应的实现步骤和代码示例。
一、概述
在Spring Boot中,实现多数据源连接和切换的方案有多种,主要包括:
- 使用AbstractRoutingDataSource实现动态数据源切换
- 使用MP提供的Dynamic-datasource多数据源框架
- 通过自定义注解在方法或类上指定数据源
- 使用数据库代理中间件
每种方案都有其独特的优势和适用场景,下面将分别进行详细阐述。
二、使用AbstractRoutingDataSource实现动态数据源切换
AbstractRoutingDataSource是Spring框架提供的一个抽象类,用于根据用户定义的规则选择当前的数据源。通过继承这个类,并实现其抽象方法determineCurrentLookupKey,我们可以实现动态数据源切换。
步骤:
- 定义数据源枚举:用于标识不同的数据源。
public enum DataSourceType {MASTER("master"),SLAVE("slave");private String value;DataSourceType(String value) {this.value = value;}public String getValue() {return value;}
}
- 创建DynamicDataSource类:继承AbstractRoutingDataSource,并重写determineCurrentLookupKey方法。
public class DynamicDataSource extends AbstractRoutingDataSource {private static final ThreadLocal<String> CONTEXT_HOLDER = new ThreadLocal<>();public DynamicDataSource(DataSource defaultTargetDataSource, Map<Object, Object> targetDataSources) {super.setDefaultTargetDataSource(defaultTargetDataSource);super.setTargetDataSources(targetDataSources);super.afterPropertiesSet();}@Overrideprotected Object determineCurrentLookupKey() {return CONTEXT_HOLDER.get();}public static void setDataSourceType(String dataSource) {CONTEXT_HOLDER.set(dataSource);}public static String getDataSourceType() {return CONTEXT_HOLDER.get();}public static void clearDataSourceType() {CONTEXT_HOLDER.remove();}
}
- 配置数据源:在Spring Boot的配置文件中配置多个数据源,并在配置类中创建这些数据源,将它们注入到DynamicDataSource中。
@Configuration
public class DataSourceConfig {@Bean@ConfigurationProperties(prefix = "spring.datasource.master")public DataSource masterDataSource() {return DataSourceBuilder.create().build();}@Bean@ConfigurationProperties(prefix = "spring.datasource.slave")public DataSource slaveDataSource() {return DataSourceBuilder.create().build();}@Beanpublic DataSource dataSource() {Map<Object, Object> targetDataSources = new HashMap<>();targetDataSources.put(DataSourceType.MASTER.getValue(), masterDataSource());targetDataSources.put(DataSourceType.SLAVE.getValue(), slaveDataSource());DynamicDataSource dataSource = new DynamicDataSource(masterDataSource(), targetDataSources);return dataSource;}
}
- 使用AOP切换数据源:通过自定义注解和AOP,在方法执行前后切换数据源。
@Aspect
@Component
public class DataSourceAspect {@Before("@annotation(dataSource)")public void changeDataSource(JoinPoint point, DataSource dataSource) {DynamicDataSource.setDataSourceType(dataSource.value());}@After("@annotation(dataSource)")public void clearDataSource(JoinPoint point, DataSource dataSource) {DynamicDataSource.clearDataSourceType();}
}
自定义注解:
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.TYPE})
public @interface DataSource {DataSourceType value() default DataSourceType.MASTER;
}
- 在业务方法上使用注解:
@Service
public class MyService {@DataSource(DataSourceType.SLAVE)public void someMethod() {// 业务逻辑}
}
三、使用MP提供的Dynamic-datasource多数据源框架
MP(MyBatis-Plus)提供了Dynamic-datasource多数据源框架,简化了多数据源的配置和管理。
步骤:
- 引入依赖:在pom.xml文件中添加Dynamic-datasource的依赖。
<dependency><groupId>com.baomidou</groupId><artifactId>dynamic-datasource-spring-boot-starter</artifactId><version>最新版本</version>
</dependency>
- 配置数据源:在application.yml或application.properties文件中配置多个数据源。
spring:datasource:dynamic:primary: master # 设置默认的数据源或者数据源组,默认值即为masterdatasource:master:url: jdbc:mysql://localhost:3306/master_dbusername: rootpassword: rootdriver-class-name: com.mysql.cj.jdbc.Driverslave:url: jdbc:mysql://localhost:3306/slave_dbusername: rootpassword: rootdriver-class-name: com.mysql.cj.jdbc.Driver
- 使用注解或配置类指定数据源:在业务方法或配置类上使用@DS注解指定数据源。
@Service
public class MyService {@DS("slave")public void someMethod() {// 业务逻辑}
}
四、通过自定义注解在方法或类上指定数据源
这种方案与使用AbstractRoutingDataSource实现动态数据源切换类似,但更加灵活和直观。通过自定义注解,我们可以直接在方法或类上指定使用哪个数据源。
步骤:
- 定义数据源枚举和自定义注解(同上)。
- 创建数据源上下文类(同上)。
- 配置数据源(同上)。
- 使用AOP切换数据源(同上)。
- 在业务方法上使用注解(同上)。
五、使用数据库代理中间件
数据库代理中间件,如Mycat、Sharding-JDBC等,提供了更加灵活和强大的多数据源管理和分片功能。这些中间件通常支持读写分离、分库分表、数据聚合等功能,可以大大简化多数据源的配置和管理。
步骤:
- 选择并引入中间件:根据业务需求选择合适的数据库代理中间件,并在项目中引入相应的依赖。
- 配置中间件:在配置文件中配置中间件的相关参数,如数据源、分片规则等。
- 使用中间件:通过中间件提供的接口或配置,实现多数据源连接和切换。
六、总结
在Spring Boot中实现多数据源连接和切换的方案有多种,每种方案都有其独特的优势和适用场景。使用AbstractRoutingDataSource实现动态数据源切换具有较高的灵活性和可控性;使用MP提供的Dynamic-datasource多数据源框架可以简化配置和管理;通过自定义注解在方法或类上指定数据源则更加直观和易用;使用数据库代理中间件则提供了更加灵活和强大的多数据源管理和分片功能。在实际应用中,我们可以根据业务需求和技术栈选择合适的方案,以实现多数据源连接和切换。
相关文章:
Spring Boot中实现多数据源连接和切换的方案
Spring Boot中实现多数据源连接和切换的方案 在Spring Boot项目中,随着业务需求的增长,我们往往需要连接多个数据库,即实现多数据源连接和切换。这种需求可能源于数据库的读写分离、微服务架构下的服务拆分、数据分库分表等场景。本文将详细…...
科技资讯|谷歌Play应用商店有望支持 XR 头显,AR / VR设备有望得到发展
据 Android Authority 报道,谷歌似乎正在为其 Play 商店增加对 XR 头显的支持。该媒体在 Play 商店的代码中发现了相关的线索,包括一个代表头显的小图标以及对“XR 头显”的提及。 谷歌也可能改变了此前拒绝将 Play 商店引入 Meta Quest 头显的决定。今…...
关于read/write 网络IO、硬盘IO的区别
对于read/write API,在数据在不超过指定的长度的时候有多少读多少,没有数据则会一直等待。 因此,对于网络IO,由于我们无法知道网络对面什么时候准备好数据,什么时候发起数据。所以使用read/write的话,可能…...
vue2开发 对接后端(go语言)常抛异常情况以及处理方法汇总
背景 在Vue2开发中,与后端(Go语言)接口对接时出现异常通常是由于前后端之间的数据交互出现了问题。常见的异常包括数据格式不匹配、请求方法不匹配、请求头部信息错误、跨域请求问题等。 常见异常 如出现报错提示: json : can…...
LSTM:解决梯度消失与长期依赖问题
LSTM:解决梯度消失与长期依赖问题 长短期记忆网络(LSTM)是一种特殊类型的递归神经网络(RNN),设计用来克服标准RNN在处理长序列数据时遇到的梯度消失问题。下面是对您提供的LSTM特性描述的详细解释…...
Kafka在大数据处理中的作用及其工作原理
Kafka在大数据处理中扮演着至关重要的角色,其作用及工作原理可以从以下几个方面进行解释: 一、Kafka的作用 消息队列: Kafka作为一个高性能、高可伸缩性的消息队列,能够有效地解耦数据生产者和消费者之间的关系,实现…...
w~自动驾驶~合集5
我自己的原文哦~ https://blog.51cto.com/whaosoft/12304427 # 智能驾驶仿真测试的『虚幻』与『真实』 先给大家讲个故事:某主机厂计划构建一套智能驾驶仿真环境,但需同时满足“对外展示”和“项目使用”两方面需求,与供应商商讨一个月后&…...
Java优先队列的使用
1. 优先队列的定义 PriorityQueue继承了Queue接口,底层默认是一个小根堆。 PriorityQueue<Integer> queuenew PriorityQueue<>(); 2. 常用方法 方法描述boolean offer(E e)入队列E poll()出队列E peek()得到队首元素 int size() 返回集合中的元素个…...
20241105,LeetCode 每日一题,用 Go 实现两数之和的非暴力解法
题目 给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。 你可以假设每种输入只会对应一个答案,并且你不能使用两次相同的元素。 你可以按任意顺序返回答案。 …...
mysql之命令行基础指令
一:安装好mysql后,注册好账号密码。 二:在命令行进行登录的指令如下 mysql -u用户名 -p 例如:mysql -uroot -p; 然后按下回车,进入输入密码。 三:基本指令: 1:查看当前账户的所有…...
使用Django Channels实现WebSocket实时通信
💓 博客主页:瑕疵的CSDN主页 📝 Gitee主页:瑕疵的gitee主页 ⏩ 文章专栏:《热点资讯》 使用Django Channels实现WebSocket实时通信 Django Channels 简介 环境搭建 安装 Django 和 Channels 创建 Django 项目 配置 A…...
「Mac畅玩鸿蒙与硬件27」UI互动应用篇4 - 猫与灯的互动应用
本篇将带领你实现一个趣味十足的互动应用,用户点击按钮时猫会在一排灯之间移动,猫所在的位置灯会亮起(on),其余灯会熄灭(off)。应用会根据用户的操作动态更新灯光状态和文本提示当前亮灯的位置&…...
Spring-Day4
12.HelloSpring <?xml version"1.0" encoding"UTF-8"?> <beans xmlns"http://www.springframework.org/schema/beans"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance" xmlns:util"http://www.springframework…...
C#-类:成员属性
数据成员 ≠ 属性 成员属性 属性可以理解为一种封装 成员属性概念:一般是用来保护成员变量的 成员属性的使用和变量一样,外部用对象点出 get中需要return内容 ; set中用value表示传入的内容 get和set语句块中可以加逻辑处理。应用&#…...
qt QDragEnterEvent详解
1、概述 QDragEnterEvent是Qt框架中用于处理拖放进入事件的一个类。当用户将一个拖拽对象(如文件、文本或其他数据)拖动到支持拖放操作的窗口部件(widget)上时,系统会触发QDragEnterEvent事件。这个类允许开发者在拖拽…...
Vue项目与IE浏览器的兼容性分析(Vue|ElementUI)
总体分析 Vue.js的兼容性在不同版本间有所差异,具体针对IE浏览器的推荐版本如下: Vue 2.x 官方支持:Vue 2.x版本官方宣布支持IE9及以上版本的IE浏览器。限制与Polyfill:虽然Vue 2.x支持IE9及以上版本,但在使用时可能…...
【C++之STL】一文学会使用 string
文章目录 1. STL导读1. 1 什么是STL1. 2 STL的版本1. 3 STL六大组件1. 4 STL的重要性1. 5 STL的学习1. 6 STL系列博客的规划 2. string2. 1 为什么学习string类?2. 2 标准库中的string2. 3 基本构造2. 4 尾插与输出运算符重载2. 5 构造函数2. 6 赋值运算符重载2. 7 容量操作2.…...
好用的办公套件--- ONLYOFFICE
目录 引言 UI界面 ONLYOFFICE 协作空间 使用协作空间三步走 一、注册与登录 二、创建房间 三、上传与编辑文档 ONLYOFFICE协作空间的安全性 ONLYOFFICE 文档 关于 ONLYOFFICE 引言 ONLYOFFICE 桌面编辑器 ONLYOFFICE是一款功能全面的办公套件,支持文档、表…...
Android View事件分发
目录 1.什么是View事件分发? 2.事件的类型 3.事件的发生 4.事件分发的方法 4.1 dispatchTouchEvent() 4.2 onTouchEvent() 4.3 onInterceptTouchEvent() 5.滑动冲突 5.1 外部拦截法 5.2内部拦截法 6.onTouch的执行高于onClick 7. onTouch()和onTouchEve…...
攻防世界GFSJ1229 Three
题目编号:GFSJ1229 解题过程 1. 附件下载是三个压缩包A.zip B.zip C.zip和一个python程序Three.py 2. A.zip可以直接解压出来,内容如下: 2022-08-27 20:16:04.246131 Func A0*X0B0 2022-08-27 20:16:05.116859 Read_Data A0.txt->A0(28829613228…...
19c补丁后oracle属主变化,导致不能识别磁盘组
补丁后服务器重启,数据库再次无法启动 ORA01017: invalid username/password; logon denied Oracle 19c 在打上 19.23 或以上补丁版本后,存在与用户组权限相关的问题。具体表现为,Oracle 实例的运行用户(oracle)和集…...
conda相比python好处
Conda 作为 Python 的环境和包管理工具,相比原生 Python 生态(如 pip 虚拟环境)有许多独特优势,尤其在多项目管理、依赖处理和跨平台兼容性等方面表现更优。以下是 Conda 的核心好处: 一、一站式环境管理:…...
基于ASP.NET+ SQL Server实现(Web)医院信息管理系统
医院信息管理系统 1. 课程设计内容 在 visual studio 2017 平台上,开发一个“医院信息管理系统”Web 程序。 2. 课程设计目的 综合运用 c#.net 知识,在 vs 2017 平台上,进行 ASP.NET 应用程序和简易网站的开发;初步熟悉开发一…...
java调用dll出现unsatisfiedLinkError以及JNA和JNI的区别
UnsatisfiedLinkError 在对接硬件设备中,我们会遇到使用 java 调用 dll文件 的情况,此时大概率出现UnsatisfiedLinkError链接错误,原因可能有如下几种 类名错误包名错误方法名参数错误使用 JNI 协议调用,结果 dll 未实现 JNI 协…...
Spring Boot+Neo4j知识图谱实战:3步搭建智能关系网络!
一、引言 在数据驱动的背景下,知识图谱凭借其高效的信息组织能力,正逐步成为各行业应用的关键技术。本文聚焦 Spring Boot与Neo4j图数据库的技术结合,探讨知识图谱开发的实现细节,帮助读者掌握该技术栈在实际项目中的落地方法。 …...
C++八股 —— 单例模式
文章目录 1. 基本概念2. 设计要点3. 实现方式4. 详解懒汉模式 1. 基本概念 线程安全(Thread Safety) 线程安全是指在多线程环境下,某个函数、类或代码片段能够被多个线程同时调用时,仍能保证数据的一致性和逻辑的正确性…...
HDFS分布式存储 zookeeper
hadoop介绍 狭义上hadoop是指apache的一款开源软件 用java语言实现开源框架,允许使用简单的变成模型跨计算机对大型集群进行分布式处理(1.海量的数据存储 2.海量数据的计算)Hadoop核心组件 hdfs(分布式文件存储系统)&a…...
网站指纹识别
网站指纹识别 网站的最基本组成:服务器(操作系统)、中间件(web容器)、脚本语言、数据厍 为什么要了解这些?举个例子:发现了一个文件读取漏洞,我们需要读/etc/passwd,如…...
IP如何挑?2025年海外专线IP如何购买?
你花了时间和预算买了IP,结果IP质量不佳,项目效率低下不说,还可能带来莫名的网络问题,是不是太闹心了?尤其是在面对海外专线IP时,到底怎么才能买到适合自己的呢?所以,挑IP绝对是个技…...
mac 安装homebrew (nvm 及git)
mac 安装nvm 及git 万恶之源 mac 安装这些东西离不开Xcode。及homebrew 一、先说安装git步骤 通用: 方法一:使用 Homebrew 安装 Git(推荐) 步骤如下:打开终端(Terminal.app) 1.安装 Homebrew…...
