SpringBoot动态切换数据源

article/2025/9/30 22:43:17

1、配置文件中配置多个数据库连接

# mysql配置
spring.datasource.local.jdbc-url=jdbc:mysql://192.168.1.115:3308/cq_njdd?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai
spring.datasource.local.username=root
spring.datasource.local.password=root3308
spring.datasource.local.driver-class-name=com.mysql.cj.jdbc.Driverspring.datasource.remote.jdbc-url=jdbc:mysql://192.168.1.115:8307/cq_njdd?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai
spring.datasource.remote.username=root
spring.datasource.remote.password=root2022
spring.datasource.remote.driver-class-name=com.mysql.cj.jdbc.Driver

这里需要注意如果SpringBoot版本是2.0之后的版本,需要把【url】和【driverClassName】写成【jdbc-url】和【driver-class-name】,否则会报错【jdbcUrl is required with driverClassName.】

 数据库连接池配置

spring.datasource.type=com.zaxxer.hikari.HikariDataSource
spring.datasource.hikari.minimum-idle=10
# 连接池中允许的最大连接数
spring.datasource.hikari.maximum-pool-size=200
# 自动提交从池中返回的连接
spring.datasource.hikari.auto-commit=true
# 连接允许在池中闲置的最长时间,超时则被释放(retired)
spring.datasource.hikari.idle-timeout=30000
spring.datasource.hikari.pool-name=ServiceTaskHikariCP
# 一个连接的生命时长(毫秒),超时而且没被使用则被释放(retired),缺省:30分钟,建议设置比数据库超时时长少30秒,参考MySQLwait_timeout参数(show variables like '%timeout%';)
spring.datasource.hikari.max-lifetime=1200000
# 等待连接池分配连接的最大时长(毫秒),超过这个时长还没可用的连接则发生SQLException
spring.datasource.hikari.connection-timeout=30000# 验证连接是否有效。此参数必须设置为非空字符串,下面三项设置成true才能生效
spring.datasource.dbcp2.validation-query=select 1
# 指明是否在从池中取出连接前进行检验,如果检验失败,则从池中去除连接并尝试取出另一个
spring.datasource.dbcp2.test-on-borrow=true
# 指明是否在归还到池中前进行检验
spring.datasource.dbcp2.test-on-return=false
# 验证连接的有效性
spring.datasource.dbcp2.test-while-idle=true
# 空闲连接回收的时间间隔,与test-while-idle一起使用,设置5分钟
spring.datasource.dbcp2.time-between-eviction-runs-millis=300000
# 连接池空闲连接的有效时间 ,设置30分钟
spring.datasource.dbcp2.soft-min-evictable-idle-time-millis=1800000

 不加配置的话会报No operations allowed after connection closed.异常。


2、数据源枚举类

自定义数据源枚举类,这里配置了两个数据源,则创建两个枚举。

public enum DataSourceType {REMOTE,LOCAL
}

3、注入数据源

生成bean。单一数据源与Mybatis整合时将DataSource数据源作为参数构建【SqlSessionFactory】,而多个数据源的话只需要将作为参数的数据源改为动态的数据源即可。

下面将配置的数据源全部注入到bean中,其中可设置默认数据源。留作之后调用。

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;@Configuration
public class DataSourceConfig {@Bean@ConfigurationProperties("spring.datasource.remote")public DataSource remoteDataSource() {return DataSourceBuilder.create().build();}@Bean@ConfigurationProperties("spring.datasource.local")public DataSource localDataSource() {return DataSourceBuilder.create().build();}@Bean(name = "dynamicDataSource")@Primarypublic DynamicDataSource dataSource(DataSource remoteDataSource, DataSource localDataSource) {Map<Object, Object> targetDataSources = new HashMap<>();targetDataSources.put(DataSourceType.REMOTE.name(), remoteDataSource);targetDataSources.put(DataSourceType.LOCAL.name(), localDataSource);DynamicDataSource dynamicDataSource = new DynamicDataSource();// 注入目标数据源,可以是多个dynamicDataSource.setTargetDataSources(targetDataSources);// 注入默认数据源,只能是一个dynamicDataSource.setDefaultTargetDataSource(localDataSource);return dynamicDataSource ;}
}

4、切换数据源

SpringBoot动态切换数据源主要依靠AbstractRoutingDataSource类,这个抽象类中有一个属性为【targetDataSources】

 该属性为Map结构,所有需要切换的数据源都存放在其中,根据指定的KEY进行切换。当然还有一个默认的数据源。

而切换数据源则需要重写该抽象类中的【determineCurrentLookupKey】抽象方法,该方法的返回值决定了需要切换的数据源key,然后根据这个key去之前的【targetDataSources】Map中取数据源。

 所以我们需要重写【determineCurrentLookupKey】方法,如下:

import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;public class DynamicDataSource extends AbstractRoutingDataSource {@Overrideprotected Object determineCurrentLookupKey() {return DynamicDataSourceContextHolder.getDataSourceType();}
}

5、切换数据源管理类

数据源属于公共资源,考虑到多线程的情况下,我们将数据源存储在【ThreadLocal】中,保证线程隔离。

public class DynamicDataSourceContextHolder {private static final ThreadLocal<String> CONTEXT_HOLDER = new ThreadLocal<>();public static void setDataSourceType(String dataSourceType){CONTEXT_HOLDER.set(dataSourceType);}public static String getDataSourceType(){return CONTEXT_HOLDER.get();}public static void clearDataSourceType(){CONTEXT_HOLDER.remove();}
}

6、自定义多数据源切换注解

为了操作方便且低耦合,定义一个切换数据源的注解,如下:

import java.lang.annotation.*;@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DataSource {DataSourceType value() default DataSourceType.LOCAL;
}

7、AOP切面拦截

切面的作用就是在注解的方法执行前,取DataSource注解【value】值设置到【ThreadLocal】中,然后在方法执行后清除掉【ThreadLocal】中的key,保证如果不切换数据源时使用默认的数据源。

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;import java.lang.reflect.Method;@Aspect
@Order(1)
@Component
public class DataSourceAspect {@Pointcut("@annotation(com.bw.note.config.datasource.DataSource)")public void dsPointCut() {}@Around("dsPointCut()")public Object around(ProceedingJoinPoint point) throws Throwable {MethodSignature signature = (MethodSignature) point.getSignature();Method method = signature.getMethod();DataSource dataSource = method.getAnnotation(DataSource.class);if (dataSource != null) {DynamicDataSourceContextHolder.setDataSourceType(dataSource.value().name());}try {return point.proceed();} finally {DynamicDataSourceContextHolder.clearDataSourceType();}}
}

8、切换数据源注解实际使用

直接在实现方法上使用自定义的注解即可。


 9、SpringBoot启动类

启动类的【SpringBootApplication】注解加上【exclude = DataSourceAutoConfiguration.class】属性。

@SpringBootApplication(scanBasePackages = "com.bw",exclude = DataSourceAutoConfiguration.class)
@MapperScan("com.bw.note.mapper")
public class NoteServiceApplication {public static void main(String[] args) {SpringApplication.run(NoteServiceApplication.class, args);}}

参考资料

https://blog.csdn.net/qq_36997144/article/details/123439244


http://chatgpt.dhexx.cn/article/IPl3JGWD.shtml

相关文章

springboot jpa 多数据源配置

1.yml多数据源配置 amdb,josdb,josdbqy&#xff0c;分别为自定义数据源名称&#xff0c;type指定数据源使用的连接池。 2.新建类DataSourceProperties用于读取yml文件中的自定义数据源属性 Component public class DataSourceProperties {Value("${spring.datasource.am…

Spring Boot使用动态数据源

文章目录 前言一、什么是动态数据源二、动态数据源实现1.实现原理2.实现过程 前言 有这样一个场景&#xff0c;现在要开发一个数据API功能&#xff0c;用户自己编写数据源脚本&#xff0c;在界面任意选择一个数据源&#xff0c;可选择的数据源列表中数据源类型是多样的&#x…

SpringBoot整合MybatisPlus多数据源

相信在很多使用MybatisPlus框架的小伙伴都会遇到多数据源的配置问题&#xff0c;并且官网也给出了推荐使用多数据源 (dynamic-datasource-spring-boot-starter) 组件来实现。由于最近项目也在使用这个组件来实现多数据源切换&#xff0c;因此想了解一下该组件是如何运行的&…

Springboot/MybatisPlus动态切换数据源

1.1 简述 最近项目中有动态切换数据源需求&#xff0c;主要是要动态切换数据源进行数据的获取&#xff0c;现将项目中实现思路及代码提供出来&#xff0c;供大家参考。当然切换数据源还有其他的方式比如使用切面的方式&#xff0c;其实大体思路是一样的。 1.2 设计思路与代码…

Spring数据源配置

目录 Spring相关的API ApplicationContext的继承体系 ApplicationContext的实现类 getBean()方法使用 Spring配置数据源(连接池) 数据源的开发步骤 加载配置文件方式创建 将DateSource的创建权交给Spring容器去完成 抽取jdbc配置文件 Spring相关的API ApplicationContex…

Java 动态数据源配置

目录 一、动态数据源介绍 1. AbstractRoutingDataSource 2. 实现逻辑 二、源代码 1. 修改配置文件类 2. 创建数据源枚举 3. 数据源切换处理 4. 继承AbstractRoutingDataSource 5. 注入数据源 6. 自定义多数据源切换注解 7. AOP拦截类的实现 8. 使用切换数据源注解 …

SpringBoot实现多数据源配置

&#x1f60a; 作者&#xff1a; 一恍过去 &#x1f496; 主页&#xff1a; https://blog.csdn.net/zhuocailing3390 &#x1f38a; 社区&#xff1a; Java技术栈交流 &#x1f389; 主题&#xff1a; SpringBoot实现多数据源配置 ⏱️ 创作时间&#xff1a; 2022年06月13…

SAP 数据源

SAP BW或者BI作为数据仓库会抽取SAP系统数据和非SAP系统数据&#xff0c;源系统的主要类型有以下几种&#xff1a; 1、SAP系统&#xff1a;R/3、S/4、CRM、等&#xff0c; 2、文本文件&#xff1a;将数据库转化为XML或者CSV文件放在FTP上&#xff0c;然后去读取数据&#xf…

Python使用tsne进行高维数据可视化实战:二维可视化、三维可视化

Python使用tsne进行高维数据可视化实战:二维可视化、三维可视化 # 绘制二维可视化图像并添加标签字符函数 def plot_embedding(data, label, title):x_min, x_max = np.min(data, 0), np.max(data, 0)data = (data - x_min) / (x_max - x_min)fig = plt.figure()ax = plt.s…

降维算法PCA的应用----高维数据的可视化

文章目录 序言废话不多说看代码导入相关模块数据提取降维降维后数据信息展示新的特征矩阵 可视化关于X_dim2[yi, 0]的解释 总结 序言 当我们拿到一堆数据的时候&#xff0c;几乎不可能通过我们的肉眼分辨出数据的分布情况&#xff0c;这时候就想要通过图展示数据的分布&#x…

学习笔记 | 用距离之距离(DoD)变换改进高维数据可视化

文章目录 一、论文关键信息二、主要内容三、总结CSDN 叶庭云:https://yetingyun.blog.csdn.net/ 一、论文关键信息 论文标题:Improved visualization of high-dimensional data using the distance-of-distance transformation 论文地址:https://doi.org/10.1371/journal.…

数据可视化的历史

数据可视化的历史 可视化发展史与测量、绘画、人类现代文明的启蒙和科技的发展一脉相承。在地图、科学与工程制图、统计图表中&#xff0c;可视化理念与技术已经应用和发展了数百年。 17世纪之前&#xff1a;图表萌芽 16世纪时&#xff0c;人类已经掌握了精确的观测技术和设…

【数据可视化】复杂高维多元数据的可视化

1 高维多元数据 每个数据对象有两个或两个以上独立或者相关属性的数据。高维指数据具有多个独立属性&#xff0c;多元指数据具有多个相关属性。由于研究者在很多情况下不确定数据的属性是否独立&#xff0c;因此通常简单地称之为多元数据。例如&#xff1a;电脑配置。 高维多元…

平行坐标图:高维数据可视化必备图形

关于数据可视化&#xff0c;我们之前分享过很多基础图表和进阶图表&#xff0c;都是一些我们常见的图表&#xff0c;如折线图&#xff0c;柱状图&#xff0c;饼图等等。今天分享一个大家应该见过但是不那么熟悉的图表-平行坐标图。 平行坐标图的定义 平行坐标图可以说是折线图…

Umap高维数据可视化与降维

Umap解决高维数据可视化的问题&#xff0c;以及高效降维。 Umap地址:https://github.com/lmcinnes/umap 文档地址&#xff1a;UMAP: Uniform Manifold Approximation and Projection for Dimension Reduction — umap 0.5 documentation 1.pip通过清华镜像安装方式&#xff…

【数据艺术科技1】基于pyhon的高维数据可视化。(1、2维)

引言 描述性分析是与数据科学项目甚至特定研究相关的任何分析生命周期的核心组成部分之一。数据聚合、汇总和可视化是支持这一数据分析领域的一些主要支柱。从传统商业智能时代到如今的人工智能时代&#xff0c;数据可视化一直是一种强大的工具&#xff0c;并因其在提取正确信…

python高维数据可视化_【机器学习】(十六)主成分分析PCA:高维数据可视化、特征提取...

主成分分析(PCA)是一种旋转数据集的方法,旋转后的特征在统计上不相关。 用PCA做数据变换 首先,算法在原始数据点集中,找到方差最大的方向(包含最多信息),标记为‘成分1’。->找到与“成分1”正交(成直角)且包含最多信息的方向,标记为“成分2”。利用这一过程找到的方向…

TSNE 高维数据可视化

TSNE 高维数据可视化 标签&#xff1a; python 机器学习 神经网络 在神经网络中&#xff0c;我们最后一层一般都是高纬度的数据&#xff0c;但是有时候我们可能想看一下这些高纬度数据的分布情况&#xff0c;这个时候就需要用TSNE&#xff0c;其实TSNE本质上就是先利用PCA降维…

PCA实现高维数据可视化

1 简介 PCA&#xff08;Principal Component Analysis&#xff09;即主成分分析是最常见的降维方法&#xff0c; 它是一种统计方法。用于高维数据集的探索与可视化&#xff0c;还可用于数据的压缩和预处理。可通过正交变换把具有相关性的高维变量转换为线性无关的低维变量&…

高维数据可视化之t-SNE算法

https://blog.csdn.net/hustqb/article/details/78144384 t-sne数学原理https://zhuanlan.zhihu.com/p/57937096 什么是t-SNE&#xff1f; t-SNE的主要用途是可视化和探索高维数据。 它由Laurens van der Maatens和Geoffrey Hinton在JMLR第九卷(2008年)中开发并出版。 t-SNE…