当前位置: 首页 > news >正文

Spring Boot中实现多数据源连接和切换的方案

Spring Boot中实现多数据源连接和切换的方案

在Spring Boot项目中,随着业务需求的增长,我们往往需要连接多个数据库,即实现多数据源连接和切换。这种需求可能源于数据库的读写分离、微服务架构下的服务拆分、数据分库分表等场景。本文将详细探讨Spring Boot中实现多数据源连接和切换的多种方案,并给出相应的实现步骤和代码示例。

一、概述

在Spring Boot中,实现多数据源连接和切换的方案有多种,主要包括:

  1. 使用AbstractRoutingDataSource实现动态数据源切换
  2. 使用MP提供的Dynamic-datasource多数据源框架
  3. 通过自定义注解在方法或类上指定数据源
  4. 使用数据库代理中间件

每种方案都有其独特的优势和适用场景,下面将分别进行详细阐述。

二、使用AbstractRoutingDataSource实现动态数据源切换

AbstractRoutingDataSource是Spring框架提供的一个抽象类,用于根据用户定义的规则选择当前的数据源。通过继承这个类,并实现其抽象方法determineCurrentLookupKey,我们可以实现动态数据源切换。

步骤

  1. 定义数据源枚举:用于标识不同的数据源。
public enum DataSourceType {MASTER("master"),SLAVE("slave");private String value;DataSourceType(String value) {this.value = value;}public String getValue() {return value;}
}
  1. 创建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();}
}
  1. 配置数据源:在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;}
}
  1. 使用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;
}
  1. 在业务方法上使用注解
@Service
public class MyService {@DataSource(DataSourceType.SLAVE)public void someMethod() {// 业务逻辑}
}
三、使用MP提供的Dynamic-datasource多数据源框架

MP(MyBatis-Plus)提供了Dynamic-datasource多数据源框架,简化了多数据源的配置和管理。

步骤

  1. 引入依赖:在pom.xml文件中添加Dynamic-datasource的依赖。
<dependency><groupId>com.baomidou</groupId><artifactId>dynamic-datasource-spring-boot-starter</artifactId><version>最新版本</version>
</dependency>
  1. 配置数据源:在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
  1. 使用注解或配置类指定数据源:在业务方法或配置类上使用@DS注解指定数据源。
@Service
public class MyService {@DS("slave")public void someMethod() {// 业务逻辑}
}
四、通过自定义注解在方法或类上指定数据源

这种方案与使用AbstractRoutingDataSource实现动态数据源切换类似,但更加灵活和直观。通过自定义注解,我们可以直接在方法或类上指定使用哪个数据源。

步骤

  1. 定义数据源枚举和自定义注解(同上)。
  2. 创建数据源上下文类(同上)。
  3. 配置数据源(同上)。
  4. 使用AOP切换数据源(同上)。
  5. 在业务方法上使用注解(同上)。
五、使用数据库代理中间件

数据库代理中间件,如Mycat、Sharding-JDBC等,提供了更加灵活和强大的多数据源管理和分片功能。这些中间件通常支持读写分离、分库分表、数据聚合等功能,可以大大简化多数据源的配置和管理。

步骤

  1. 选择并引入中间件:根据业务需求选择合适的数据库代理中间件,并在项目中引入相应的依赖。
  2. 配置中间件:在配置文件中配置中间件的相关参数,如数据源、分片规则等。
  3. 使用中间件:通过中间件提供的接口或配置,实现多数据源连接和切换。
六、总结

在Spring Boot中实现多数据源连接和切换的方案有多种,每种方案都有其独特的优势和适用场景。使用AbstractRoutingDataSource实现动态数据源切换具有较高的灵活性和可控性;使用MP提供的Dynamic-datasource多数据源框架可以简化配置和管理;通过自定义注解在方法或类上指定数据源则更加直观和易用;使用数据库代理中间件则提供了更加灵活和强大的多数据源管理和分片功能。在实际应用中,我们可以根据业务需求和技术栈选择合适的方案,以实现多数据源连接和切换。

相关文章:

Spring Boot中实现多数据源连接和切换的方案

Spring Boot中实现多数据源连接和切换的方案 在Spring Boot项目中&#xff0c;随着业务需求的增长&#xff0c;我们往往需要连接多个数据库&#xff0c;即实现多数据源连接和切换。这种需求可能源于数据库的读写分离、微服务架构下的服务拆分、数据分库分表等场景。本文将详细…...

科技资讯|谷歌Play应用商店有望支持 XR 头显,AR / VR设备有望得到发展

据 Android Authority 报道&#xff0c;谷歌似乎正在为其 Play 商店增加对 XR 头显的支持。该媒体在 Play 商店的代码中发现了相关的线索&#xff0c;包括一个代表头显的小图标以及对“XR 头显”的提及。 谷歌也可能改变了此前拒绝将 Play 商店引入 Meta Quest 头显的决定。今…...

关于read/write 网络IO、硬盘IO的区别

对于read/write API&#xff0c;在数据在不超过指定的长度的时候有多少读多少&#xff0c;没有数据则会一直等待。 因此&#xff0c;对于网络IO&#xff0c;由于我们无法知道网络对面什么时候准备好数据&#xff0c;什么时候发起数据。所以使用read/write的话&#xff0c;可能…...

vue2开发 对接后端(go语言)常抛异常情况以及处理方法汇总

背景 在Vue2开发中&#xff0c;与后端&#xff08;Go语言&#xff09;接口对接时出现异常通常是由于前后端之间的数据交互出现了问题。常见的异常包括数据格式不匹配、请求方法不匹配、请求头部信息错误、跨域请求问题等。 常见异常 如出现报错提示&#xff1a; json : can…...

LSTM:解决梯度消失与长期依赖问题

LSTM&#xff1a;解决梯度消失与长期依赖问题 长短期记忆网络&#xff08;LSTM&#xff09;是一种特殊类型的递归神经网络&#xff08;RNN&#xff09;&#xff0c;设计用来克服标准RNN在处理长序列数据时遇到的梯度消失问题。下面是对您提供的LSTM特性描述的详细解释&#xf…...

Kafka在大数据处理中的作用及其工作原理

Kafka在大数据处理中扮演着至关重要的角色&#xff0c;其作用及工作原理可以从以下几个方面进行解释&#xff1a; 一、Kafka的作用 消息队列&#xff1a; Kafka作为一个高性能、高可伸缩性的消息队列&#xff0c;能够有效地解耦数据生产者和消费者之间的关系&#xff0c;实现…...

w~自动驾驶~合集5

我自己的原文哦~ https://blog.51cto.com/whaosoft/12304427 # 智能驾驶仿真测试的『虚幻』与『真实』 先给大家讲个故事&#xff1a;某主机厂计划构建一套智能驾驶仿真环境&#xff0c;但需同时满足“对外展示”和“项目使用”两方面需求&#xff0c;与供应商商讨一个月后&…...

Java优先队列的使用

1. 优先队列的定义 PriorityQueue继承了Queue接口&#xff0c;底层默认是一个小根堆。 PriorityQueue<Integer> queuenew PriorityQueue<>(); 2. 常用方法 方法描述boolean offer(E e)入队列E poll()出队列E peek()得到队首元素 int size() 返回集合中的元素个…...

20241105,LeetCode 每日一题,用 Go 实现两数之和的非暴力解法

题目 给定一个整数数组 nums 和一个整数目标值 target&#xff0c;请你在该数组中找出 和为目标值 target 的那 两个 整数&#xff0c;并返回它们的数组下标。 你可以假设每种输入只会对应一个答案&#xff0c;并且你不能使用两次相同的元素。 你可以按任意顺序返回答案。 …...

mysql之命令行基础指令

一&#xff1a;安装好mysql后&#xff0c;注册好账号密码。 二&#xff1a;在命令行进行登录的指令如下 mysql -u用户名 -p 例如&#xff1a;mysql -uroot -p; 然后按下回车&#xff0c;进入输入密码。 三&#xff1a;基本指令&#xff1a; 1&#xff1a;查看当前账户的所有…...

使用Django Channels实现WebSocket实时通信

&#x1f493; 博客主页&#xff1a;瑕疵的CSDN主页 &#x1f4dd; Gitee主页&#xff1a;瑕疵的gitee主页 ⏩ 文章专栏&#xff1a;《热点资讯》 使用Django Channels实现WebSocket实时通信 Django Channels 简介 环境搭建 安装 Django 和 Channels 创建 Django 项目 配置 A…...

「Mac畅玩鸿蒙与硬件27」UI互动应用篇4 - 猫与灯的互动应用

本篇将带领你实现一个趣味十足的互动应用&#xff0c;用户点击按钮时猫会在一排灯之间移动&#xff0c;猫所在的位置灯会亮起&#xff08;on&#xff09;&#xff0c;其余灯会熄灭&#xff08;off&#xff09;。应用会根据用户的操作动态更新灯光状态和文本提示当前亮灯的位置&…...

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#-类:成员属性

数据成员 ≠ 属性 成员属性 属性可以理解为一种封装 成员属性概念&#xff1a;一般是用来保护成员变量的 成员属性的使用和变量一样&#xff0c;外部用对象点出 get中需要return内容 &#xff1b; set中用value表示传入的内容 get和set语句块中可以加逻辑处理。应用&#…...

qt QDragEnterEvent详解

1、概述 QDragEnterEvent是Qt框架中用于处理拖放进入事件的一个类。当用户将一个拖拽对象&#xff08;如文件、文本或其他数据&#xff09;拖动到支持拖放操作的窗口部件&#xff08;widget&#xff09;上时&#xff0c;系统会触发QDragEnterEvent事件。这个类允许开发者在拖拽…...

Vue项目与IE浏览器的兼容性分析(Vue|ElementUI)

总体分析 Vue.js的兼容性在不同版本间有所差异&#xff0c;具体针对IE浏览器的推荐版本如下&#xff1a; Vue 2.x 官方支持&#xff1a;Vue 2.x版本官方宣布支持IE9及以上版本的IE浏览器。限制与Polyfill&#xff1a;虽然Vue 2.x支持IE9及以上版本&#xff0c;但在使用时可能…...

【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是一款功能全面的办公套件&#xff0c;支持文档、表…...

Android View事件分发

目录 1.什么是View事件分发&#xff1f; 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

​ 题目编号&#xff1a;GFSJ1229 解题过程 1. 附件下载是三个压缩包A.zip B.zip C.zip和一个python程序Three.py 2. A.zip可以直接解压出来&#xff0c;内容如下: 2022-08-27 20:16:04.246131 Func A0*X0B0 2022-08-27 20:16:05.116859 Read_Data A0.txt->A0(28829613228…...

2026年5款AI封面生成工具对比实测,短视频矩阵如何批量产出高点击率封面?

日更30条视频后&#xff0c;封面成了最耗人力的瓶颈一位做知识类矩阵账号的运营同学最近在 CSDN 社区发帖&#xff1a;‘每天剪完40条口播视频&#xff0c;还要手动调色、加标题、选字体、抠图、对齐网格——光是封面就卡住整条流水线。’这不是个例。在抖音、小红书、B站三端同…...

YCbCr 转 RGB:揭秘那串神奇公式背后的百年故事

一、一个让我"开窍"的翻译故事 我大学时有个学语言学的朋友&#xff0c;他给我讲过一个让我至今难忘的故事。他说翻译界有一个著名的"中间语言"问题——如果你要把一本书从 50 种语言互相翻译&#xff0c;最笨的办法是给每两种语言之间都准备一个翻译&…...

3分钟掌握ZeroOmega:让浏览器代理切换变得轻松高效

3分钟掌握ZeroOmega&#xff1a;让浏览器代理切换变得轻松高效 【免费下载链接】ZeroOmega Manage and switch between multiple proxies quickly & easily. 项目地址: https://gitcode.com/gh_mirrors/ze/ZeroOmega ZeroOmega 是一款强大的浏览器代理管理工具&…...

高斯混合期望传播算法:突破高阶MIMO检测性能瓶颈

1. 项目概述与核心挑战在无线通信系统的演进中&#xff0c;多输入多输出&#xff08;MIMO&#xff09;技术早已不是新鲜概念&#xff0c;它通过部署多根天线&#xff0c;在相同的频带内同时传输多个独立的数据流&#xff0c;从而成倍地提升了频谱效率和系统容量。然而&#xff…...

贝叶斯分层建模与机器学习插补:应对经济数据稀疏性的稳健分析框架

1. 项目概述&#xff1a;当数据稀缺成为常态&#xff0c;我们如何看清经济转型的脉络&#xff1f;在低收入和中等收入国家&#xff08;LMICs&#xff09;从事经济研究或政策分析&#xff0c;最常遇到的困境不是模型不够先进&#xff0c;而是数据“不够用”。你手头的数据集可能…...

魔兽争霸3终极优化指南:5分钟解决画面拉伸与帧率限制难题

魔兽争霸3终极优化指南&#xff1a;5分钟解决画面拉伸与帧率限制难题 【免费下载链接】WarcraftHelper Warcraft III Helper , support 1.20e, 1.24e, 1.26a, 1.27a, 1.27b 项目地址: https://gitcode.com/gh_mirrors/wa/WarcraftHelper 还在为经典游戏魔兽争霸3在现代电…...

BurpSuite集成AES加解密与动态签名实战指南

1. 这不是“又一个加解密接口”&#xff0c;而是BurpSuite工作流的断点重铸你有没有在做API安全测试时&#xff0c;反复遇到这种场景&#xff1a;目标接口对请求体做了AES加密&#xff0c;且每次请求还带一个动态生成的签名字段&#xff1b;你用Burp Suite抓到包&#xff0c;想…...

Burp Suite安装失败原因与Java环境配置全解

1. 为什么Burp Suite安装失败不是“运气差”&#xff0c;而是环境逻辑没对齐 Burp Suite安装问题总结——这标题听起来像一份运维日志&#xff0c;但实际是每个刚接触Web安全测试的人必经的“成人礼”。我带过十几期渗透测试实操班&#xff0c;92%的新手在第一天卡在Burp启动环…...

机器学习赋能系统综述:SyROCCo项目实战解析与NLP应用指南

1. 项目概述&#xff1a;当系统综述遇上机器学习如果你做过系统综述&#xff0c;一定对那种“望洋兴叹”的感觉不陌生。面对动辄成千上万的文献&#xff0c;光是筛选、阅读、提取数据这几步&#xff0c;就足以耗掉一个团队数月甚至数年的精力。更头疼的是&#xff0c;等你终于完…...

保姆级教程:为你的CentOS7服务器手动安装GNOME桌面,告别黑屏与鼠标箭头

从零构建CentOS7图形化工作站&#xff1a;GNOME桌面完整安装与深度优化指南当你第一次面对CentOS7漆黑的命令行界面时&#xff0c;那种茫然无措的感觉我深有体会。三年前接手公司第一台生产服务器时&#xff0c;我盯着闪烁的光标整整十分钟不敢敲下任何命令——毕竟在Ubuntu漂亮…...