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

spring-data 一统江湖,玩转多种数据源

1、起因

因为要在项目中同时访问redis,mongo和mysql三种数据库,而且因为偏向spring-data,所以都使用了spring-data

在使用的过程中如果不做配置发现会有冲突,这篇文章也是解决这个问题,避免以后遇到同样的问题不知所措

2、项目实战

2.1 创建springboot项目

没啥好说的,直接一路next,使用maven管理项目

2.2 加入spring-data的配置

这里使用了mongo和mysql,也是工作中常用的两个数据库,pom中配置如下

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jpa</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-mongodb</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId><scope>runtime</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency>

2.3 配置数据源

application.yml中主要是数据库的链接信息,mysql 和mongo的

server:port: 9099
spring:data:mongodb:uri: mongodb://172.26.1.152:27017/ccp_testdatasource:driver-class-name: com.mysql.cj.jdbc.Drivertype: com.zaxxer.hikari.HikariDataSourceurl: jdbc:mysql://172.26.1.152:3306/cx_test?characterEncoding=utf8&serverTimezone=UTCusername: rootpassword: 123456hikari:minimum-idle: 10maximum-pool-size: 150connection-test-query: SELECT 1 FROM DUALconnection-timeout: 600idleTimeout: 30000maxLifetime: 40000validation-timeout: 300login-timeout: 10jpa:show-sql: true

2.4 配置entity

这里是使用mysql的entity,mongo中直接复用同样的entity,

@Data
@Entity
@Table(name = "test_table")
@Document(collection = "test_table")
public class TestTable implements Serializable {private static final long serialVersionUID = 1L;    @Id    @Column(name = "id", nullable = false)@GeneratedValue(strategy = GenerationType.IDENTITY)private Integer id;    @Column(name = "name")private String name;}

2.5 分别创建Repository

mysql的Repository,操作mysql 数据

package com.xin.mongoandmysql.dao.mysql;import com.xin.mongoandmysql.entity.TestTable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;public interface TestTableRepository extends JpaRepository<TestTable, Integer>, JpaSpecificationExecutor<TestTable> {}

mongo的Repository,操作mongo 数据

package com.xin.mongoandmysql.dao.mongo;import com.xin.mongoandmysql.entity.TestTable;
import org.springframework.data.mongodb.repository.MongoRepository;public interface MongoTableRepository extends MongoRepository<TestTable, String> {
}

注:上面两个repo 放在不同的包下面,不同数据库集成的repo不同

 

2.6 配置扫描的包

@SpringBootApplication
@EnableMongoRepositories(basePackages = {"com.xin.mongoandmysql.dao.mongo"})
@EnableJpaRepositories(basePackages = "com.xin.mongoandmysql.dao.mysql")
public class MongoAndMysqlApplication {public static void main(String[] args) {SpringApplication.run(MongoAndMysqlApplication.class, args);    }
}

这里很重要,配置mysql 和mongo的扫描路径,也是这里的难点,后面会讲原理和为什么

2.7 测试

创建一个简单的controller就行

@RestController
public class TestController {@ResourceMongoTableRepository mongoTableRepository;@ResourceTestTableRepository testTableRepository;@GetMapping("/test")public void test(){TestTable testTable = new TestTable();testTable.setName("香菜");testTable.setId(1);mongoTableRepository.save(testTable);testTableRepository.save(testTable);}
}

直接调用接口,就可以看到数据存入数据库,OK,实验结束。

2.8 看下结果

可以看到mysql和mongo 都存入了数据

3、打怪之旅

3.1 服务器启动不了,bean注册失败

最初的时候因为没有分包扫描,导致服务器启动失败,之前没怎么注意过这件事

原因是因为jpa和mongo都会去根路径下扫描所有的repo,然后生成动态代理,

mysql 扫描到testRepo会生成代理

mongo扫描到testRepo也会生成代理

两者都会想容器进行注册,这就导致bean出现重名的现象

源码:

org.springframework.data.repository.config.RepositoryConfigurationDelegate#registerRepositoriesIn

这里可以看到,RepositoryConfigurationDelegate来自spring-data-commons的包,mysql和mongo都会调用

在源码中可以看到有个basePackages的属性,如果不配置,默认是从根路径进行扫描,就会出现被代理多次注册的问题

3.2 spring-data 是如何实现repo中的接口的

在一个项目中有多个 spring-data 模块时,尝试为特定实体创建一个接口,该接口没有使用特定的持久性技术注释进行注释

(如 javax.persistence 中的@Entity,或 mongo 中的@Document),通过从 spring-data-commons 模块(即 Repository 或 CrudRepository)扩展接口 - 这根本不起作用,因为 spring 基本上不知道你的实体与哪个数据存储相关联。

在 Spring 内部有一个抽象,称为RepositoryFactoryBeanSupport。尝试将 spring data jdbc starter 和 spring data mongodb starter 添加到您的项目中。你会注意到,在类路径中有2 个不同的 RepositoryFactoryBeanSupport 实现:

  1. JdbcRepositoryFactoryBean(来自spring data jdbc starter)
  2. MongoRepositoryFactoryBean(来自spring data mongo starter)

如何让不同的repo关联相应的数据库

  1. 扩展特定于技术的存储库。例如,如果希望实体 A 与 PostgreSQL 关联,则不要使用 CrudRepository - 应该使用 JpaRepository。如果希望实体 B 与 Redis 相关联,请使用 RedisRepository 等。
  2. 使用注释对您的实体进行注释,表明它隶属于特定的数据存储。如@Entity、@Document、@Table 等。

总结

注:分包扫描是解决问题的重点

很久之前写的文章了,在看之前回想一下,依然没有清晰的理解

复习一遍就掌握了,学而时习之不亦乐乎

关注点赞,一键三连,感谢支持

相关文章:

spring-data 一统江湖,玩转多种数据源

1、起因 因为要在项目中同时访问redis&#xff0c;mongo和mysql三种数据库&#xff0c;而且因为偏向spring-data&#xff0c;所以都使用了spring-data 在使用的过程中如果不做配置发现会有冲突&#xff0c;这篇文章也是解决这个问题&#xff0c;避免以后遇到同样的问题不知所…...

【EMC专题】为什么PCB上的单端阻抗控制在50欧?

每当我们在发板后和PCB板厂沟通说有些走线需要阻抗控制,控制在多少多少。其实我们所说的阻抗是传输线的特性阻抗。特性阻抗是不能用万用表测量出来的,他由传输线的结构以及材料决定,与传输线的长度、信号的幅度、频率等均无关。 特性阻抗的概念 当电磁波在电缆上…...

想自学写个操作系统,有哪些推荐看的书籍?

前言 哈喽&#xff0c;我是子牙&#xff0c;一个很卷的硬核男人。喜欢研究底层&#xff0c;聚焦做那些大家想学没地方学的课程&#xff1a;手写操作系统、手写虚拟机、手写编程语言… 今天我们将站在一个自学者的角度来聊聊如何实现自己的操作系统。并为大家推荐几本能够帮助你…...

深入理解Java虚拟机:JVM高级特性与最佳实践-总结-7

深入理解Java虚拟机&#xff1a;JVM高级特性与最佳实践-总结-7 类文件结构概述无关性的基石 虚拟机类加载机制概述类加载的时机 类文件结构 代码编译的结果从本地机器码转变为字节码&#xff0c;是存储格式发展的一小步&#xff0c;却是编程语言发展的一大步 概述 我们写的程…...

ES6中flat与flatMap使用

1、方法介绍 数组的成员有时还是数组&#xff0c;Array.prototype.flat()用于将嵌套的数组“拉平”&#xff0c;变成一维的数组。该方法返回一个新数组&#xff0c;对原数据没有影响。 [1, 2, [3, 4]].flat() // [1, 2, 3, 4]上面代码中&#xff0c;原数组的成员里面有一个数…...

苹果手机、电脑如何进行屏幕录制?苹果录屏功能在哪?

随着人们生活水平的提高&#xff0c;不少小伙伴都会选择苹果手机、苹果电脑作为主要的设备。因为使用苹果电脑进行办公&#xff0c;不仅仅能够提升效率&#xff0c;对于文件的安全性也是有一些保障的。那么&#xff0c;在使用苹果电脑的时候&#xff0c;如果需要有录屏的需求该…...

什么是研发 Lead Time?我悟了!

嗨&#xff0c;朋友&#xff01;你听说过「新型工伤」吗&#xff1f; 我好像「赛博确诊」了&#x1f623; 那天朋友约我吃饭&#xff0c;我下意识回复了句「好的&#xff0c;那我提一个日程」……还有上次跟一位准妈妈聊天&#xff0c;我好奇宝宝的预产期&#xff0c;结果脱口…...

android 窗口焦点介绍

背景 我们经常会遇到一种Application does not hava focused window的ANR异常&#xff0c;这种异常一般是没有焦点窗口FocusedWindow导致,且这类异常只会发生在key事件的派发&#xff0c;因为key事件是需要找到一个焦点窗口然后再派发&#xff0c;而触摸事件只需要找到当前显示…...

研发工程师玩转Kubernetes——构建、推送自定义镜像

这几节我们都是使用microk8s学习kubernetes&#xff0c;于是镜像库我们也是使用它的插件——registry。 开启镜像库插件 microk8s enable registry模拟开发环境 我们使用Python作为开发语言来进行本系列的演练。 安装Python sudo apt install python3.11安装Pip3 pip3用于…...

[网络安全]DVWA之XSS(Stored)攻击姿势及解题详析合集

[网络安全]DVWA之XSS&#xff08;Stored&#xff09;攻击姿势及解题详析合集 XSS(Stored)-low level源代码姿势基于Message板块基于Name板块 XSS(Stored)-medium level源代码姿势双写绕过大小写绕过Xss标签绕过 XSS(Stored)-high level源代码姿势&#xff1a;Xss标签绕过 XSS(S…...

VP记录:Codeforces Round 873 (Div. 2) A~D1

传送门:CF 前题提要:因为本场比赛的D题让我十分难受.刚开始以为 r − l 1 r-l1 r−l1与 r − l r-l r−l应该没什么不同.但是做的时候发现假设是 r − l 1 r-l1 r−l1的话我们可以使用线段树来维护,但是 r − l r-l r−l就让线段树维护的难度大大增加,这导致我十分烦躁,所以…...

【C++】函数提高

欢迎来到博主 Apeiron 的博客&#xff0c;祝您旅程愉快 &#xff01;时止则止&#xff0c;时行则行。动静不失其时&#xff0c;其道光明。 目录 1、缘起 2、函数默认参数 3、函数占位参数 4、总结 1、缘起 以前学习过了函数的基本用法和功能&#xff0c;现在是时候学习函数…...

【可持续能源:让我们迈向绿色、可持续未来的道路】

作为未来的主要能源来源&#xff0c;可持续能源技术确实有潜力改变我们的世界。随着全球对传统化石燃料的依赖程度逐渐降低&#xff0c;可再生能源已成为许多国家推进能源转型的首选。 从太阳能和风能到地热能和潮汐能&#xff0c;可持续能源技术已经在许多方面取得了重大突破…...

ES6中数组新增了哪些扩展?

一、扩展运算符的应用 ES6通过扩展元素符...&#xff0c;好比 rest 参数的逆运算&#xff0c;将一个数组转为用逗号分隔的参数序列 console.log(...[1, 2, 3]) // 1 2 3console.log(1, ...[2, 3, 4], 5) // 1 2 3 4 5[...document.querySelectorAll(div)] // [<div>, …...

【算法】动态规划

一、基础知识 动态规划的基本思想&#xff1a;将待求解问题分解成若干个子问题&#xff0c;如果各个子问题不是独立的&#xff0c;不同的子问题的个数只是多项式量级&#xff0c;为避免大量的重复计算&#xff0c;用一个表记录所有已解决的子问题的答案&#xff0c;而在需要的…...

HNOI2014 世界树

洛谷P3233 [HNOI2014]世界树 题目大意 有一棵 n n n个点的树&#xff0c;每个点有一个编号&#xff0c;有 q q q次操作。对于每次操作&#xff0c;给出 m m m个点并称为议事点&#xff0c;树上各个点由离这个点最近的议事点管理&#xff08;如果有多个议事点离这个点最近&…...

在MyBatis XML文件中处理特殊符号的方法,如“>”、“<”、“>=”、“<=”这些符号XML会报错如何处理

前言 在MyBatis的XML映射文件中&#xff0c;我们经常需要使用特殊符号&#xff0c;比如"大于"、"小于"、"大于等于"、"小于等于"等比较操作符。然而&#xff0c;这些符号在XML中具有特殊的含义&#xff0c;因此需要进行特殊处理&…...

第三章--第一篇:什么是对话系统?

对话系统是一种人机交互的技术,旨在使计算机能够与人类进行自然而流畅的对话。它是人工智能领域的重要研究方向,具有重要的实际应用价值和广泛的普适性。 首先,对话系统的重要性在于它可以提供高效便捷的人机交互方式。传统的人机界面,如图形用户界面(GUI)和命令行界面(…...

项目基础搭建

一、项目创建 1.下载并安装nodejs 下载完成后&#xff0c;查看node版本 winR 快捷键&#xff0c;cmd确定&#xff0c;进入后台黑框 node -v查看npm安装路径 npm root -g安装cnpm镜像 npm install -g cnpm --registryhttps://registry.npm.taobao.org&#xff1a;查看npm版…...

PFCdocumentation_FISH Rules and Usage

目录 FISH Scripting FISH Rules and Usage Lines Data Types Reserved Names for Functions and Variables Scope of Variables Functions: Structure, Evaluation, and Calling Scheme Arithmetic: Expressions and Type Conversions Redefining FISH Functions Ex…...

KubeSphere 容器平台高可用:环境搭建与可视化操作指南

Linux_k8s篇 欢迎来到Linux的世界&#xff0c;看笔记好好学多敲多打&#xff0c;每个人都是大神&#xff01; 题目&#xff1a;KubeSphere 容器平台高可用&#xff1a;环境搭建与可视化操作指南 版本号: 1.0,0 作者: 老王要学习 日期: 2025.06.05 适用环境: Ubuntu22 文档说…...

以下是对华为 HarmonyOS NETX 5属性动画(ArkTS)文档的结构化整理,通过层级标题、表格和代码块提升可读性:

一、属性动画概述NETX 作用&#xff1a;实现组件通用属性的渐变过渡效果&#xff0c;提升用户体验。支持属性&#xff1a;width、height、backgroundColor、opacity、scale、rotate、translate等。注意事项&#xff1a; 布局类属性&#xff08;如宽高&#xff09;变化时&#…...

如何在看板中有效管理突发紧急任务

在看板中有效管理突发紧急任务需要&#xff1a;设立专门的紧急任务通道、重新调整任务优先级、保持适度的WIP&#xff08;Work-in-Progress&#xff09;弹性、优化任务处理流程、提高团队应对突发情况的敏捷性。其中&#xff0c;设立专门的紧急任务通道尤为重要&#xff0c;这能…...

spring:实例工厂方法获取bean

spring处理使用静态工厂方法获取bean实例&#xff0c;也可以通过实例工厂方法获取bean实例。 实例工厂方法步骤如下&#xff1a; 定义实例工厂类&#xff08;Java代码&#xff09;&#xff0c;定义实例工厂&#xff08;xml&#xff09;&#xff0c;定义调用实例工厂&#xff…...

鱼香ros docker配置镜像报错:https://registry-1.docker.io/v2/

使用鱼香ros一件安装docker时的https://registry-1.docker.io/v2/问题 一键安装指令 wget http://fishros.com/install -O fishros && . fishros出现问题&#xff1a;docker pull 失败 网络不同&#xff0c;需要使用镜像源 按照如下步骤操作 sudo vi /etc/docker/dae…...

AI编程--插件对比分析:CodeRider、GitHub Copilot及其他

AI编程插件对比分析&#xff1a;CodeRider、GitHub Copilot及其他 随着人工智能技术的快速发展&#xff0c;AI编程插件已成为提升开发者生产力的重要工具。CodeRider和GitHub Copilot作为市场上的领先者&#xff0c;分别以其独特的特性和生态系统吸引了大量开发者。本文将从功…...

Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析

Java求职者面试指南&#xff1a;Spring、Spring Boot、MyBatis框架与计算机基础问题解析 一、第一轮提问&#xff08;基础概念问题&#xff09; 1. 请解释Spring框架的核心容器是什么&#xff1f;它在Spring中起到什么作用&#xff1f; Spring框架的核心容器是IoC容器&#…...

Java数值运算常见陷阱与规避方法

整数除法中的舍入问题 问题现象 当开发者预期进行浮点除法却误用整数除法时,会出现小数部分被截断的情况。典型错误模式如下: void process(int value) {double half = value / 2; // 整数除法导致截断// 使用half变量 }此时...

站群服务器的应用场景都有哪些?

站群服务器主要是为了多个网站的托管和管理所设计的&#xff0c;可以通过集中管理和高效资源的分配&#xff0c;来支持多个独立的网站同时运行&#xff0c;让每一个网站都可以分配到独立的IP地址&#xff0c;避免出现IP关联的风险&#xff0c;用户还可以通过控制面板进行管理功…...

在树莓派上添加音频输入设备的几种方法

在树莓派上添加音频输入设备可以通过以下步骤完成&#xff0c;具体方法取决于设备类型&#xff08;如USB麦克风、3.5mm接口麦克风或HDMI音频输入&#xff09;。以下是详细指南&#xff1a; 1. 连接音频输入设备 USB麦克风/声卡&#xff1a;直接插入树莓派的USB接口。3.5mm麦克…...