springboot jpa 多数据源配置

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

1.yml多数据源配置

amdb,josdb,josdbqy,分别为自定义数据源名称,type指定数据源使用的连接池。

2.新建类DataSourceProperties用于读取yml文件中的自定义数据源属性

@Component
public class DataSourceProperties {@Value("${spring.datasource.amdb.jdbc-url}")private String amdbUrl;@Value("${spring.datasource.amdb.username}")private String amdbUserName;@Value("${spring.datasource.amdb.password}")private String amdbPassword;@Value("${spring.datasource.amdb.driver-class-name}")private String amdbDriverClass;@Value("${spring.datasource.josdb.jdbc-url}")private String josdbUrl;@Value("${spring.datasource.josdb.username}")private String josdbUserName;@Value("${spring.datasource.josdb.password}")private String josdbPassword;@Value("${spring.datasource.josdb.driver-class-name}")private String josdbDriverClass;@Value("${spring.datasource.josdbqy.jdbc-url}")private String josdbqyUrl;@Value("${spring.datasource.josdbqy.username}")private String josdbqyUserName;@Value("${spring.datasource.josdbqy.password}")private String josdbqyPassword;@Value("${spring.datasource.josdbqy.driver-class-name}")private String josdbqyDriverClass;public String getAmdbUrl() {return amdbUrl;}public void setAmdbUrl(String amdbUrl) {this.amdbUrl = amdbUrl;}public String getAmdbUserName() {return amdbUserName;}public void setAmdbUserName(String amdbUserName) {this.amdbUserName = amdbUserName;}public String getAmdbPassword() {return amdbPassword;}public void setAmdbPassword(String amdbPassword) {this.amdbPassword = amdbPassword;}public String getAmdbDriverClass() {return amdbDriverClass;}public void setAmdbDriverClass(String amdbDriverClass) {this.amdbDriverClass = amdbDriverClass;}public String getJosdbUrl() {return josdbUrl;}public void setJosdbUrl(String josdbUrl) {this.josdbUrl = josdbUrl;}public String getJosdbUserName() {return josdbUserName;}public void setJosdbUserName(String josdbUserName) {this.josdbUserName = josdbUserName;}public String getJosdbPassword() {return josdbPassword;}public void setJosdbPassword(String josdbPassword) {this.josdbPassword = josdbPassword;}public String getJosdbDriverClass() {return josdbDriverClass;}public void setJosdbDriverClass(String josdbDriverClass) {this.josdbDriverClass = josdbDriverClass;}public String getJosdbqyUrl() {return josdbqyUrl;}public void setJosdbqyUrl(String josdbqyUrl) {this.josdbqyUrl = josdbqyUrl;}public String getJosdbqyUserName() {return josdbqyUserName;}public void setJosdbqyUserName(String josdbqyUserName) {this.josdbqyUserName = josdbqyUserName;}public String getJosdbqyPassword() {return josdbqyPassword;}public void setJosdbqyPassword(String josdbqyPassword) {this.josdbqyPassword = josdbqyPassword;}public String getJosdbqyDriverClass() {return josdbqyDriverClass;}public void setJosdbqyDriverClass(String josdbqyDriverClass) {this.josdbqyDriverClass = josdbqyDriverClass;}
}

3.创建类DynamicDataSource继承AbstractRoutingDataSource并实determineCurrentLookupKey()

方法,从DataSourceContextHolder动态获取对应线程的数据源。

public class DynamicDataSource extends AbstractRoutingDataSource {@Overrideprotected Object determineCurrentLookupKey() {return DataSourceContextHolder.getDataSource();}}

 

4.再创建DataSourceConfig类,创建数据源


@Configuration
public class DataSourceConfig {@AutowiredDataSourceProperties dataSourceProperties;@Bean(name = "amdb")public DataSource amdb() {HikariDataSource amdb = new HikariDataSource();amdb.setJdbcUrl(dataSourceProperties.getAmdbUrl());amdb.setDriverClassName(dataSourceProperties.getAmdbDriverClass());amdb.setUsername(dataSourceProperties.getAmdbUserName());amdb.setPassword(dataSourceProperties.getAmdbPassword());amdb.setPoolName("HikariPool-amdb");amdb.setAutoCommit(true);amdb.setReadOnly(false);amdb.setConnectionTestQuery("SELECT 1;");return amdb;}@Bean(name = "josdb")public DataSource josdb() {HikariDataSource josdb = new HikariDataSource();josdb.setJdbcUrl(dataSourceProperties.getJosdbUrl());josdb.setDriverClassName(dataSourceProperties.getJosdbDriverClass());josdb.setUsername(dataSourceProperties.getJosdbUserName());josdb.setPassword(dataSourceProperties.getJosdbPassword());josdb.setPoolName("HikariPool-josdb");josdb.setAutoCommit(true);josdb.setReadOnly(false);josdb.setConnectionTestQuery("SELECT 1;");return josdb;}@Bean(name = "josdbqy")public DataSource josdbqy() {HikariDataSource josdbqy = new HikariDataSource();josdbqy.setJdbcUrl(dataSourceProperties.getJosdbqyUrl());josdbqy.setDriverClassName(dataSourceProperties.getJosdbqyDriverClass());josdbqy.setUsername(dataSourceProperties.getJosdbqyUserName());josdbqy.setPassword(dataSourceProperties.getJosdbqyPassword());josdbqy.setPoolName("HikariPool-josdbqy");josdbqy.setAutoCommit(true);josdbqy.setReadOnly(false);josdbqy.setConnectionTestQuery("SELECT 1;");return josdbqy;}@Bean(name = "amdbJdbcTemplate")public JdbcTemplate amdbJdbcTemplate(@Qualifier("amdb") DataSource dataSource) {return new JdbcTemplate(dataSource);}@Bean(name = "josdbJdbcTemplate")public JdbcTemplate josdbJdbcTemplate(@Qualifier("josdb") DataSource dataSource) {return new JdbcTemplate(dataSource);}@Bean(name = "josdbqyJdbcTemplate")public JdbcTemplate josdbqyJdbcTemplate(@Qualifier("josdbqy") DataSource dataSource) {return new JdbcTemplate(dataSource);}@Primary@Bean("dynamicDataSource")public DataSource dynamicDataSource() {Map<Object, Object> targetDataSources = new HashMap<>(3);targetDataSources.put(DataSourceTypeEnum.amdb, amdb());targetDataSources.put(DataSourceTypeEnum.josdb, josdb());targetDataSources.put(DataSourceTypeEnum.josdbqy, josdbqy());// 添加数据源名称到列表DataSourceContextHolder.dataSourceIds.add(DataSourceTypeEnum.amdb.name());DataSourceContextHolder.dataSourceIds.add(DataSourceTypeEnum.josdb.name());DataSourceContextHolder.dataSourceIds.add(DataSourceTypeEnum.josdbqy.name());DynamicDataSource dynamicDataSource = new DynamicDataSource();// 如果没有指定数据源自动切换主数据源dynamicDataSource.setDefaultTargetDataSource(amdb());dynamicDataSource.setTargetDataSources(targetDataSources);return dynamicDataSource;}@Beanpublic PlatformTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) {JpaTransactionManager jpaTransactionManager = new JpaTransactionManager(entityManagerFactory);jpaTransactionManager.setDataSource(dynamicDataSource());return jpaTransactionManager;}

创建对应的三个数据源,amdb,josdb,josdbqy,再创建对应的jdbctemplate, 再创建指定数据源的方法dynamicDataSource(),以及最后指定对应的Jpa事务管理器。

5.创建DataSourceContextHolder动态数据源上下文管理

public class DataSourceContextHolder {// 存放当前线程使用的数据源类型private static final ThreadLocal<DataSourceTypeEnum> contextHolder = new ThreadLocal<>();//存放数据源idpublic static List<String> dataSourceIds = new ArrayList<String>();// 设置数据源public static void setDataSource(DataSourceTypeEnum type) {contextHolder.set(type);}// 获取数据源public static DataSourceTypeEnum getDataSource() {return contextHolder.get();}// 清除数据源public static void clearDataSource() {contextHolder.remove();}//判断当前数据源是否存在public static boolean isContainsDataSource(String dataSourceId) {return dataSourceIds.contains(dataSourceId);}
}

6.创建自定义注解DS类

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.METHOD })
public @interface DS {DataSourceTypeEnum value() default DataSourceTypeEnum.amdb;
}

7.使用aop的切面来切换数据源。

@Aspect
@Order(-10) // 保证该AOP在@Transactional之前执行
@Component
public class DynamicDataSourceAspect {private static final Logger logger = LoggerFactory.getLogger(DynamicDataSourceAspect.class);@Before(value = "@annotation(source)")public void changeDataSource(JoinPoint point, DS source) throws Exception {DataSourceTypeEnum currentSource = source.value();logger.info("Change DataSource To:[" + currentSource + "]");DataSourceContextHolder.setDataSource(currentSource);}@After(value = "@annotation(source)")public void restoreDataSource(JoinPoint point, DS source) {// 方法执行完毕之后,销毁当前数据源信息,进行垃圾回收。DataSourceContextHolder.clearDataSource();logger.info("Clear Change DataSource...");}}

8.在service的实现类来使用数据源的切换,在所需方法上加上DS注解以及对应的数据源类型,即可实现数据源切换

 9.加上枚举类

public enum DataSourceTypeEnum {amdb, josdb, josdbqy
}

 

 

 

 


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

相关文章

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…

Python 数据可视化学习笔记 之高维数据可视化及其方法

一、高维数据 高维数据泛指高维&#xff08;multidimensional&#xff09; 和多变量&#xff08;multivariate&#xff09;数据 -- 高维是指数据具有多个独立属性 -- 多变量是指数据具有多个相关属性 高维数据可视化的挑战&#xff1a; 如何呈现单个数据点的各属性的数据值分…