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…...
Qwen3-4B-Thinking开源镜像教程:Chainlit前端对接企业微信机器人
Qwen3-4B-Thinking开源镜像教程:Chainlit前端对接企业微信机器人 1. 引言:当大模型遇到企业级应用 想象一下这个场景:你刚部署好一个强大的AI模型,它能帮你写代码、分析问题、生成文档。但每次使用,你都得打开一个特…...
造相Z-Image文生图模型v2:3步搭建你的专属AI画师
造相Z-Image文生图模型v2:3步搭建你的专属AI画师 1. 为什么选择Z-Image v2作为你的AI画师 在众多文生图模型中,造相Z-Image v2以其独特的优势脱颖而出。作为阿里通义万相团队开源的高性能模型,它原生支持768768及以上分辨率的高清图像生成&…...
从概念到上线:基于快马平台构建一个功能完备的qun329实战应用
今天想和大家分享一个实战项目经验——如何从零开始构建一个功能完备的qun329群组应用。这个项目不仅包含了基础的群聊功能,还实现了消息状态同步、文件共享等生产级需求,整个过程在InsCode(快马)平台上完成,特别适合想快速验证复杂场景的开发…...
LangChain 与 LangGraph 介绍
一、AI 时代下的编程范式 1. Vibe Coding 氛围编程 1.1 Vibe Coding 的起源 在过去十年间,低代码 / 无代码平台和 AI 代码助手持续冲击着软件开发行业。如今,一种被称为 Vibe Coding 的新兴实践突然走红,甚至颠覆了人们对 "…...
SenseVoice-Small ONNX开源方案:支持私有化部署的国产语音识别新标杆
SenseVoice-Small ONNX开源方案:支持私有化部署的国产语音识别新标杆 1. 项目简介 SenseVoice-Small ONNX是一个专为普通硬件设计的轻量化语音识别工具。基于FunASR开源框架的SenseVoiceSmall模型,通过Int8量化技术大幅降低资源消耗,让语音…...
基于Ascend 950的Cube编程
直播回放链接:基于下一代硬件的Cube编程_哔哩哔哩_bilibili...
告别微信传文件!用LocalSend+cpolar搭建私人远程文件库(Windows保姆级教程)
打造私人云存储:LocalSend与cpolar的极简文件共享方案 你是否经历过这样的场景:在咖啡馆急需调取家里电脑的一份文档,却只能对着微信传输助手的"文件大小超过限制"提示干着急?或是出差在外,发现手机里缺少一…...
5分钟搞定电脑风扇噪音!FanControl超详细配置指南让你告别“飞机起飞“
5分钟搞定电脑风扇噪音!FanControl超详细配置指南让你告别"飞机起飞" 【免费下载链接】FanControl.Releases This is the release repository for Fan Control, a highly customizable fan controlling software for Windows. 项目地址: https://gitcod…...
实战react项目:基于快马ai快速构建包含图表与导航的用户数据仪表盘
最近在做一个用户数据仪表盘项目,正好用React配合Ant Design实现了一套完整的界面。这种包含导航、图表和动态数据的页面在后台系统中很常见,记录下我的实现思路和踩坑经验。 项目结构规划 首先用create-react-app初始化项目,然后按功能模块…...
Claude Code性能优化实战:如何让AI编程助手在大型项目中飞起来
Claude Code性能优化实战:如何让AI编程助手在大型项目中飞起来 大型代码库就像一座迷宫,而Claude Code则是你手中的智能地图。但当项目规模膨胀到数十万行代码时,这张地图的加载速度可能会让你抓狂。本文将分享一系列经过实战验证的性能优化技…...
