详细分析Java中的多数据源

目录

  • 1. 方式一
  • 2. 方式二(常用)

1. 方式一

采用jpa的依赖包:

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

配置对应的数据源:application.properties

# 主数据源配置
spring.datasource.primary.url=jdbc:mysql://localhost:3306/primarydb
spring.datasource.primary.username=username
spring.datasource.primary.password=password
spring.datasource.primary.driver-class-name=com.mysql.cj.jdbc.Driver# 辅助数据源配置
spring.datasource.secondary.url=jdbc:mysql://localhost:3306/secondarydb
spring.datasource.secondary.username=username
spring.datasource.secondary.password=password
spring.datasource.secondary.driver-class-name=com.mysql.cj.jdbc.Driver

创建数据源配置:

@Configuration
@EnableTransactionManagement
public class DataSourceConfig {@Primary@Bean(name = "primaryDataSource")@ConfigurationProperties(prefix = "spring.datasource.primary")public DataSource primaryDataSource() {return DataSourceBuilder.create().build();}@Bean(name = "secondaryDataSource")@ConfigurationProperties(prefix = "spring.datasource.secondary")public DataSource secondaryDataSource() {return DataSourceBuilder.create().build();}@Primary@Bean(name = "entityManagerFactory")public LocalContainerEntityManagerFactoryBean entityManagerFactory(EntityManagerFactoryBuilder builder, @Qualifier("primaryDataSource") DataSource dataSource) {return builder.dataSource(dataSource).packages("your.primary.entity.package").persistenceUnit("primary").build();}@Bean(name = "secondaryEntityManagerFactory")public LocalContainerEntityManagerFactoryBean secondaryEntityManagerFactory(EntityManagerFactoryBuilder builder, @Qualifier("secondaryDataSource") DataSource dataSource) {return builder.dataSource(dataSource).packages("your.secondary.entity.package").persistenceUnit("secondary").build();}@Primary@Bean(name = "transactionManager")public PlatformTransactionManager transactionManager(@Qualifier("entityManagerFactory") EntityManagerFactory entityManagerFactory) {return new JpaTransactionManager(entityManagerFactory);}@Bean(name = "secondaryTransactionManager")public PlatformTransactionManager secondaryTransactionManager(@Qualifier("secondaryEntityManagerFactory") EntityManagerFactory entityManagerFactory) {return new JpaTransactionManager(entityManagerFactory);}
}

切换数据源,此处使用@Qualifier的注解

@Service
public class YourService {@Autowired@Qualifier("primaryDataSource")private DataSource primaryDataSource;@Autowired@Qualifier("secondaryDataSource")private DataSource secondaryDataSource;@Autowiredprivate YourRepository yourRepository;@Transactional(transactionManager = "transactionManager")public void methodUsingPrimaryDataSource() {// 在这里使用主数据源}@Transactional(transactionManager = "secondaryTransactionManager")public void methodUsingSecondaryDataSource() {// 在这里使用辅助数据源}
}

2. 方式二(常用)

配置依赖包:

<dependency><groupId>com.baomidou</groupId><artifactId>dynamic-datasource-spring-boot-starter</artifactId>
</dependency>

先配置数据源:

spring:datasource:dynamic: # 多数据源配置druid: # Druid 【连接池】相关的全局配置initial-size: 1 # 初始连接数min-idle: 1 # 最小连接池数量max-active: 20 # 最大连接池数量max-wait: 600000 # 配置获取连接等待超时的时间,单位:毫秒time-between-eviction-runs-millis: 60000 # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位:毫秒min-evictable-idle-time-millis: 300000 # 配置一个连接在池中最小生存的时间,单位:毫秒max-evictable-idle-time-millis: 900000 # 配置一个连接在池中最大生存的时间,单位:毫秒validation-query: SELECT 1 FROM DUAL # 配置检测连接是否有效test-while-idle: truetest-on-borrow: falsetest-on-return: falseprimary: masterdatasource:master:name: manongurl: jdbc:mysql://10.197.2.223:3306/${spring.datasource.dynamic.datasource.master.name}?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true # MySQL Connector/J 8.X 连接的示例username: rootpassword: rootslave:name: manonglazy: true # 开启懒加载,保证启动速度url: jdbc:mysql://10.197.2.223:3306/${spring.datasource.dynamic.datasource.slave.name}?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true # MySQL Connector/J 8.X 连接的示例username: rootpassword: rootss:name: sslazy: true # 开启懒加载,保证启动速度url: jdbc:oracle:thin:@//10.197.1.200:3333/ss # Oracle 连接的示例username: rootpassword: root

之后调用的时候采取@Master或者@Slave的形式,使用哪个注解就是使用哪个数据库

也可采用@DS的注解形式,对于多数据源来说

自定义注解如下:

import org.springframework.core.annotation.AliasFor;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface Master {
}
import org.springframework.core.annotation.AliasFor;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface Slave {
}

定义自定义事务注解 @DSTransactional

import org.springframework.transaction.annotation.Transactional;
import java.lang.annotation.*;@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Transactional("dynamicTransactionManager")
public @interface DSTransactional {
}

Service层如下:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;@Service
public class YourService {private final JdbcTemplate masterJdbcTemplate;private final JdbcTemplate slaveJdbcTemplate;@Autowiredpublic YourService(@Qualifier("masterJdbcTemplate") JdbcTemplate masterJdbcTemplate,@Qualifier("slaveJdbcTemplate") JdbcTemplate slaveJdbcTemplate) {this.masterJdbcTemplate = masterJdbcTemplate;this.slaveJdbcTemplate = slaveJdbcTemplate;}@Masterpublic void doSomethingWithMaster() {// 使用主数据源进行操作}@Slavepublic void doSomethingWithSlave() {// 使用从数据源进行操作}@DSTransactionalpublic void doSomethingTransactional() {// 这个方法将使用默认数据源进行操作,因为 @Transactional 注解没有指定数据源}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/11568.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

K8S面试题学习2

参考K8S面试题&#xff08;史上最全 持续更新&#xff09;_kubernetes常见面试题-CSDN博客做的个人总结&#xff0c;规划是每天看10题&#xff0c;thx&#xff01; 1. k8s中命名空间的作用是什么&#xff1f; namespace主要用来实现不同环境/多租户的资源隔离 k8s通过将集群内…

一文汇总对比英伟达、AMD、英特尔显卡GPU

‍‍&#x1f3e1;博客主页&#xff1a; virobotics(仪酷智能)&#xff1a;LabVIEW深度学习、人工智能博主 &#x1f4d1;上期文章&#xff1a;『【仪酷LabVIEW AI工具包案例】使用LabVIEW AI工具包YOLOv5结合Dobot机械臂实现智能垃圾分类』 &#x1f37b;本文由virobotics(仪酷…

Flutter 中的 Theme 使用:全面指南

Flutter 中的 Theme 使用&#xff1a;全面指南 在 Flutter 中&#xff0c;Theme 是一种强大的机制&#xff0c;用于定义和应用全局或局部的设计风格&#xff0c;包括颜色、字体、形状等。使用 Theme 可以确保你的应用在不同设备和屏幕尺寸上保持一致的外观和感觉。 基础用法 …

AVL树的完全指南:平衡与性能

文章目录 AVL树简介AVL的操作建立一个AVL树插入操作删除操作 书写代码1.构造函数和析构函数2.获取最大值和最小值3.树的高度和节点个数3.前序中序和后序遍历4.判断树是否为空树5.四个旋转操作6.获取平衡因子7.插入操作8.删除操作9.搜索节点.h文件中的定义 总结 AVL树简介 AVL树…

ICode国际青少年编程竞赛- Python-4级训练场-嵌套for循环入门

ICode国际青少年编程竞赛- Python-4级训练场-嵌套for循环入门 1、 for i in range(3):Dev.step(3)for j in range(3):Dev.turnLeft()Dev.step(-2)Dev.turnLeft()2、 for i in range(3):Dev.turnLeft()Dev.step(4)Dev.turnRight()Dev.step(2)for i in range(4):Dev.step(2)D…

python 基础:copy和deepcopy详解

python 的copy 模块提供了 copy 和 deepcopy 两个函数来拷贝对象。copy.copy 函数用于浅拷贝&#xff0c;而copy.deepcopy 函数用于深拷贝。 我们寻常意义的拷贝就是深拷贝&#xff0c;即将被拷贝对象完全再拷贝一遍作为独立的新个体单独存在。所以改变原有被拷贝对象不会对已…

nginx目录枚举修复手册

nginx目录枚举修复手册 漏洞背景 修复方式: ssh zujian2 sudo vi /data/apps/nginx/conf/conf.d/default.conf server {

网页如何集成各社区征文活动

Helllo , 我是小恒 由于我需要腾讯云社区&#xff0c;稀土掘金以及CSDN的征文活动RSS&#xff0c;找了一下没发现&#xff0c;所以使用GET 请求接口对网页定时进行拉取清洗&#xff0c;甚至无意间做了一个简单的json格式API 最终网址:hub.liheng.work API:http://hub.liheng.wo…

升级! 测试萌新Python学习之连通数据库Pymsql增删改及封装(四)

pymysql 数据库概述python对数据库的增删改查pymysql核心操作事务事务操作pymysql工具类封装每日复习ChatGPT的回答 数据库概述 分类 关系型数据库: 安全 如, mysql oracle SQLite…database tables 行列 非关系型数据库: 高效 如, redis mongoDB…数据存储结构多样 键值对…

Python Socket

一、服务端 from socket import *def print_hi(name):print(fHi, {name})# 允许所有ip连接IP 0.0.0.0# 端口PORT 8003# 定义一次从socket缓冲区读入512个字节数据BUFFER_LEN 512# 实例化socket对象 listenSocket 用来监听的socketlistenSocket socket(AF_INET, SOCK_STREA…

主题替换解决方案-打造完善多主题

目录 01: 主题替换原理分析 02: TailWind DarkMode 原理 03: 为组件增加 Dark 适配 04: DarkMode 在复杂应用中的实现逻辑分析 05: DarkMode 在复杂应用中的实现 06: 跟随系统的主题变更 07: 总结 01: 主题替换原理分析 主题替换原理&#xff1a;通过类名来控制对应的样…

2023-2024 联邦推荐 × 顶会

目录 AAAI2024 Federated Contextual Cascading Bandits with Asynchronous Communication and Heterogeneous Users General Commerce Intelligence: Glocally Federated NLP-Based Engine for Privacy-Preserving and Sustainable Personalized Services of Multi-Merchan…

Kubernetes——命令指南

目录 前言 1.检查集群状态 2.使用Pod 3.使用部署 4.使用服务 5.使用 ConMap 和 Secret 6.调试与故障排除 7.清理 8.使用命名空间 9.管理持久卷 10.处理节点 11.资源配额和限制范围 12.访问API对象 13.总结 前言 kubectl 是针对Kubernetes集群运行命令的命令行界…

怎么通过微信小程序实现远程控制8路控制器/断路器

怎么通过微信小程序实现远程控制8路控制器/断路器呢&#xff1f; 本文描述了使用微信小程序调用HTTP接口&#xff0c;实现控制8路控制器/断路器&#xff0c;支持8路输出&#xff0c;均可独立控制&#xff0c;可接入各种电器。 可选用产品&#xff1a;可根据实际场景需求&#…

DS:顺序表、单链表的相关OJ题训练(2)

欢迎各位来到 Harper.Lee 的学习世界&#xff01; 博主主页传送门&#xff1a;Harper.Lee的博客主页 想要一起进步的uu欢迎来后台找我哦&#xff01; 一、力扣--141. 环形链表 题目描述&#xff1a;给你一个链表的头节点 head &#xff0c;判断链表中是否有环。如果链表中有某个…

提升网络性能,解决网络故障,了解AnaTraf网络流量分析仪

在当今数字化时代&#xff0c;网络性能监测与诊断(Network Performance Monitoring and Diagnosis,NPMD)成为了企业和个人关注的焦点。随着网络流量不断增长&#xff0c;确保网络的稳定性和高效性变得更加重要。在这个领域&#xff0c;AnaTraf网络流量分析仪是您不可或缺的得力…

从“金事通”带给我意想不到的来说--“数据是架构的中心”

背景 上周一个保险的销售人员来找我完成一定的售后流程。其中有一项是请我下载一个叫 金事通的 APP。说实在的我根本没听过。她说这是政治任务。我想不是有你们保险公司的APP了嘛。为什么还要我安装。没办法先安装吧。 经历了注册、人脸识别的步骤后。可以登录了。注册短信发…

使用Docker+Jar方式部署微服务工程(前后端分离)看着一篇就够了

本篇教程的使用到的技术有springboot、springcloud、Nacos、Docker、Nginx部署前后端分离访问的微服务。 部署一下Nacos 首先我们需要在服务器中&#xff08;或者本地部署启动一下Nacos&#xff09;&#xff0c;这里我采用服务器的方式进行部署&#xff0c;这里有一点不一样的…

前端开发者必备:Nginx入门实战宝典,从部署到优化一网打尽

&#x1f525; 个人主页&#xff1a;空白诗 文章目录 引言 &#x1f44b;一、Nginx简介 &#x1f4da;二、常见的Web服务器架构 &#x1f300;&#x1f4cc; 架构概述&#x1f4cc; Nginx的深入探讨 三、正向代理与反向代理 &#x1f52e;&#x1f4cc; 正向代理工作原理&#…

Leecode热题100---1:两数之和

题目&#xff1a;从nums中找出两个元素&#xff0c;它们的和等于target&#xff0c;返回下标。 C&#xff1a; 1、直接暴力法 写嵌套循环&#xff0c;让每一个元素和其他元素分别相加&#xff0c;判断和是否等于target&#xff0c;等于就返回下标。 #include <iostream>…