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

Java书签 #使用MyBatis接入多数据源

楔子:当然,世上有很多优秀的女性,我也会被她们吸引。这对男人来说是理所当然的。但目光被吸引和内心被吸引是截然不同的。- 东野圭吾《黎明之街》

今日书签

在一些应用场景中,可能需要连接多个不同的数据库,例如连接不同的数据库服务器或者连接主从数据库。这段代码就是为了实现这种多数据源的配置。

具体来说,这个类包含两个内部静态类:

  1. MyBatisDataSourceConfiguration4XMei: 这个类配置了第一个数据源,即 “xmei” 数据源。它使用了
    @Primary 注解来指示这是默认的主数据源。这个数据源配置了一个 Druid 数据源,并配置了与该数据源相关的
    SqlSessionFactory、事务管理器(DataSourceTransactionManager)和
    SqlSessionTemplate。@MapperScan 注解用于指示需要扫描哪些包下的 Mapper 接口,并使用特定的
    SqlSessionFactory。它还定义了 Mapper XML 文件的路径,以及事务管理和 SqlSessionTemplate。
  2. MyBatisDataSourceConfiguration4XWei: 这个类配置了第二个数据源,即 “xwei” 数据源。它没有使用
    @Primary 注解,因此不是默认的主数据源。它使用了 @Qualifier 注解来指定特定的 Bean
    名称,用于解决多个数据源的冲突。与第一个数据源类似,它配置了一个 Druid 数据源,并定义了与该数据源相关的
    SqlSessionFactory、事务管理器和 SqlSessionTemplate。

多数据源

使用 Service、Mapper、XML 所在包路径区分默认数据源 与 第二数据源。
直接看代码:

/*** 多数据源接入* dataSource4XMei 为 xmei 库,为默认数据源,正常使用,此处以外无其它配置* dataSource4XWei 为 xwei 库,为第二数据源,正常使用,此处以外无其它配置*/
@Configuration
public class MyBatisConfiguration {/*** 配置 SpringBoot 默认数据源,一般配置为主数据库,此为 xmei*/@Configuration@MapperScan(basePackages = {"com.cw.tan.xmei.persistence.*"}, sqlSessionFactoryRef = "sqlSessionFactory4XMei")protected static class MyBatisDataSourceConfiguration4XMei {@Bean@Primary@ConfigurationProperties("spring.datasource.druid.xmei")public DataSource dataSource4XMei() {return DruidDataSourceBuilder.create().build();}@Bean@Primarypublic SqlSessionFactory sqlSessionFactory4XMei(DataSource dataSource4XMei) throws Exception {SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();sqlSessionFactoryBean.setDataSource(dataSource4XMei);sqlSessionFactoryBean.setMapperLocations(this.resolveMapperLocations());return sqlSessionFactoryBean.getObject();}private Resource[] resolveMapperLocations() {ResourcePatternResolver resourceResolver = new PathMatchingResourcePatternResolver();List<String> mapperLocations = new ArrayList<>();mapperLocations.add("classpath*:com/cw/tan/xmei/persistence/**/*.xml");List<Resource> resources = new ArrayList();if (!CollectionUtils.isEmpty(mapperLocations)) {for (String mapperLocation : mapperLocations) {try {Resource[] mappers = resourceResolver.getResources(mapperLocation);resources.addAll(Arrays.asList(mappers));} catch (IOException e) {// ignore}}}return resources.toArray(new Resource[resources.size()]);}/*** 配置事务管理*/@Bean@Primarypublic DataSourceTransactionManager transactionManager4XMei(DataSource dataSource4XMei) {return new DataSourceTransactionManager(dataSource4XMei);}@Bean@Primarypublic SqlSessionTemplate sqlSessionTemplate4XMei(SqlSessionFactory sqlSessionFactory4XMei) {return new SqlSessionTemplate(sqlSessionFactory4XMei);}}/*** 配置第二数据源,注意 mapper 扫描路径和上面的区分开*/@Configuration@MapperScan(basePackages = {"com.cw.tan.xwei.log.mapper","com.cw.tan.xwei.sms.mapper", "com.cw.tan.xwei.job.mapper"}, sqlSessionFactoryRef = "sqlSessionFactory4XWei")protected static class MyBatisDataSourceConfiguration4XWei {@Bean(name = "dataSource4XWei")@ConfigurationProperties("spring.datasource.druid.xwei")public DataSource dataSource4XWei() {return DruidDataSourceBuilder.create().build();}@Bean(name = "sqlSessionFactory4XWei")public SqlSessionFactory sqlSessionFactory4XWei(@Qualifier("dataSource4XWei") DataSource dataSource4XWei) throws Exception {SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();sqlSessionFactoryBean.setDataSource(dataSource4XWei);sqlSessionFactoryBean.setMapperLocations(this.resolveMapperLocations());return sqlSessionFactoryBean.getObject();}private Resource[] resolveMapperLocations() {ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();List<String> mapperLocations = new ArrayList<>();mapperLocations.add("classpath*:com/cw/tan/xwei/log/**/*.xml");mapperLocations.add("classpath*:com/cw/tan/xwei/sms/**/*.xml");mapperLocations.add("classpath*:com/cw/tan/xwei/job/**/*.xml");List<Resource> resources = new ArrayList<>();if (!CollectionUtils.isEmpty(mapperLocations)) {mapperLocations.forEach(mapperLocation -> {try {Resource[] mappers = resourcePatternResolver.getResources(mapperLocation);resources.addAll(Arrays.asList(mappers));} catch (IOException e) {// ignore}});}return resources.toArray(new Resource[resources.size()]);}@Bean(name = "transactionManager4XWei")public DataSourceTransactionManager transactionManager4XWei(@Qualifier("dataSource4XWei") DataSource dataSource4XWei) {return new DataSourceTransactionManager(dataSource4XWei);}@Bean(name = "sqlSessionTemplate4XWei")public SqlSessionTemplate sqlSessionTemplate4XWei(@Qualifier("sqlSessionFactory4XWei") SqlSessionFactory sqlSessionFactory4XWei) {return new SqlSessionTemplate(sqlSessionFactory4XWei);}}
}

注意:上述配置,请确认自己的默认数据源、第二数据源对应Service、DAO文件所在的包路径,如果路径指向不对,可能会出现以下异常:
2023-08-17 16:09:33.981 [TID:] [main] WARN AnnotationConfigServletWebServerApplicationContext.refresh():559 - Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name ‘dataDataSyncController’: Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type ‘com.cw.tan.xwei.job.IDataSyncService’ available: expected single matching bean but found 2: dataSyncServiceImpl,IDataSyncService

总结

这段代码通过两个内部静态类分别配置了两个不同的数据源(xmei 和 xwei)。每个数据源配置了对应的 Druid 数据源、SqlSessionFactory、事务管理器和 SqlSessionTemplate。这种多数据源配置适用于需要访问多个不同数据库的场景,如在一个系统中同时连接多个数据库来进行不同的操作,比如主数据库和日志数据库、数据库与业务库数据同步等。

如果还需要扩展更多数据源,则可将上述 第二数据源配置 进行复制粘贴,然后做相应名称、包路径的修改即可。

相关文章:

Java书签 #使用MyBatis接入多数据源

楔子&#xff1a;当然&#xff0c;世上有很多优秀的女性&#xff0c;我也会被她们吸引。这对男人来说是理所当然的。但目光被吸引和内心被吸引是截然不同的。- 东野圭吾《黎明之街》 今日书签 在一些应用场景中&#xff0c;可能需要连接多个不同的数据库&#xff0c;例如连接不…...

神经网络基础-神经网络补充概念-23-神经网络的梯度下降法

概念 神经网络的梯度下降法是训练神经网络的核心优化算法之一。它通过调整神经网络的权重和偏差&#xff0c;以最小化损失函数&#xff0c;从而使神经网络能够逐渐逼近目标函数的最优值。 步骤 1损失函数&#xff08;Loss Function&#xff09;&#xff1a; 首先&#xff0c…...

鸿蒙3.1 设备管理DeviceManager

介绍 DeviceManager组件在OpenHarmony上提供账号无关的分布式设备的认证组网能力,并为开发者提供了一套用于分布式设备间监听、发现和认证的接口。 其组成及依赖如下所示: 总结 设备管理模块其实就是软总线的包皮服务。目前权限都是控制系统uid,但是根据官方介绍,后续可…...

Git 目录详解

一、Git目录详解 在使用Git时&#xff0c;有几个目录和文件在Git项目中扮演着重要的角色&#xff0c;下面详细介绍一下这些目录和文件的作用 1、.git目录 .git目录是Git项目的核心&#xff0c;包含了Git的版本库和元数据等重要信息。在该目录中&#xff0c;有一些重要的子目录和…...

基于springboot+vue的武汉旅游网(前后端分离)

博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战 主要内容&#xff1a;毕业设计(Javaweb项目|小程序等)、简历模板、学习资料、面试题库、技术咨询 文末联系获取 项目介绍…...

步入React正殿 - React组件设计模式

目录 扩展学习资料 高阶组件 /src/components/hoc/withTooltip.js /src/components/hoc/itemA.jsx /src/components/hoc/itemB.jsx /src/App.js 函数作为子组件【Render pprops】 函数作为子组件 /src/components/rp/itemC.jsx【父组件】 /src/components/rp/withToo…...

Java 单例模式简单介绍

何为单例模式 所谓类的单例设计模式&#xff0c;就是采取一定的方法保证在整个的软件系统中&#xff0c;对某个类只能存在一个对象实例&#xff0c;并且该类只提供一个取得其对象实例的方法。 实现思路 如果我们要让类在一个虚拟机中只能产生一个对象&#xff0c;我们首先必…...

根据源码,模拟实现 RabbitMQ - 从需求分析到实现核心类(1)

目录 一、需求分析 1.1、对 Message Queue 的认识 1.2、消息队列核心概念 1.3、Broker Server 内部关键概念 1.4、Broker Server 核心 API &#xff08;重点实现&#xff09; 1.5、交换机类型 Direct 直接交换机 Fanout 扇出交换机 Topic 主题交换机 1.6、持久化 1.7…...

企业服务器数据库遭到malox勒索病毒攻击后如何解决,勒索病毒解密

网络技术的发展不仅为企业带来了更高的效率&#xff0c;还为企业带来信息安全威胁&#xff0c;其中较为常见的就是勒索病毒攻击。近期&#xff0c;我们公司收到很多企业的求助&#xff0c;企业的服务器数据库遭到了malox勒索病毒攻击&#xff0c;导致系统内部的许多重要数据被加…...

udp与can通信的选择与比较

UDP&#xff08;用户数据报协议&#xff09;和CAN&#xff08;控制器局域网&#xff09;是两种不同的通信协议&#xff0c;它们在实时传递性上有一些区别。 UDP是一种无连接的传输协议&#xff0c;它提供了简单的、不可靠的数据传输。UDP不提供可靠性保证、流控制或重传机制。…...

HoudiniVex笔记_P24_ForceBasics力基础

原视频&#xff1a;https://www.youtube.com/playlist?listPLzRzqTjuGIDhiXsP0hN3qBxAZ6lkVfGDI Bili&#xff1a;Houdini最强VEX算法教程 - VEX for Algorithmic Design_哔哩哔哩_bilibili Houdini版本&#xff1a;19.5 1、什么是Force 本章主要讲重力、弹力、速度与质量、…...

半导体退火那些事(1)

1.半导体退火的原理 半导体材料在晶体生长和制造过程中&#xff0c;由于各种原因会出现缺陷、杂质、位错等结构性缺陷&#xff0c;导致晶格不完整&#xff0c;施加电场后的电导率较低。通过退火处理&#xff0c;可以使材料得到修复&#xff0c;结晶体内部重新排列&#xff0c;…...

MapReduce介绍

目录 ​一、什么是MapReduce 二、MapReduce 的设计思想 2.1 分而治之 2.2 构建抽象模型&#xff1a;Map和Reduce 2.3 隐藏系统层细节 三、MapReduce 的框架原理 3.1 MRv1工作原理 3.1.1 MRv1架构工作原理图 3.1.1.1 流程说明 3.1.1.1.1 作业的提交 3.1.1.1.2 作业的初始化 3…...

Redis支持的主要数据结构操作命令有哪些?

Redis支持多种数据结构操作命令&#xff0c;包括以下主要命令&#xff1a; 字符串&#xff08;Strings&#xff09;&#xff1a; SET&#xff1a;设置字符串键的值。GET&#xff1a;获取指定键的值。INCR/DECR&#xff1a;对存储整数的字符串执行加一或减一操作。APPEND&#x…...

环境与能源创新专题:地级市绿色创新、碳排放与环境规制数据

数据简介&#xff1a;推动绿色发展&#xff0c;促进人与自然和谐共生是重大战略举措。绿色发展强调“绿水青山就是金山银山”&#xff0c;人与自然和谐共生重在正确处理生态环境保护与经济发展的关系。在着力于实现绿色发展的过程中&#xff0c;绿色创新是绿色发展的重要驱动因…...

设计模式之门面模式(Facade)的C++实现

1、门面模式提出 在组件的开发过程中&#xff0c;某些接口之间的依赖是比较紧密的&#xff0c;如果某个接口发生变化&#xff0c;其他的接口也会跟着发生变化&#xff0c;这样的代码违背了代码的设计原则。门面设计模式是在外部客户程序和系统程序之间添加了一层中间接口&…...

【数理知识】向量与基的内积,Matlab 代码验证

序号内容1【数理知识】向量的坐标基表示法&#xff0c;Matlab 代码验证2【数理知识】向量与基的内积&#xff0c;Matlab 代码验证 文章目录 1. 向量与基的内积2. 二维平面向量举例3. 代码验证Ref 1. 向量与基的内积 假设存在一个二维平面内的向量 a ⃗ \vec{a} a &#xff0c…...

黑客入侵:福特汽车Sync3车机存在漏洞,黑客入侵可抹除系统数据

据福特汽车公告&#xff0c;他们发现部分2021年至2022年车型的Sync3车机存在Wi-Fi漏洞&#xff0c;该漏洞可能被黑客利用来入侵并抹除车机内的系统数据。这一漏洞源于福特车系中采用的WL18xx MCP驱动程序的内存缓冲区溢位漏洞&#xff0c;其漏洞编号为CVE-2023-29468。 这一发现…...

面试热题(单词搜索)

给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 单词必须按照字母顺序&#xff0c;通过相邻的单元格内的字母构成&#xff0c;其中“相邻”单元格是那些水平相邻或垂直相…...

自定义表格组件:实现表格中有固定列的功能逻辑

目录 1&#xff0c;效果图2&#xff0c;实现思路3&#xff0c;实现方式 1&#xff0c;效果图 可以拖动纵向滑块&#xff0c;最左边一列固定住。 以同样的道理&#xff0c;可以在右面固定一列 2&#xff0c;实现思路 作为一个table组件&#xff0c;要接受父组件中的对table的…...

三维GIS开发cesium智慧地铁教程(5)Cesium相机控制

一、环境搭建 <script src"../cesium1.99/Build/Cesium/Cesium.js"></script> <link rel"stylesheet" href"../cesium1.99/Build/Cesium/Widgets/widgets.css"> 关键配置点&#xff1a; 路径验证&#xff1a;确保相对路径.…...

Opencv中的addweighted函数

一.addweighted函数作用 addweighted&#xff08;&#xff09;是OpenCV库中用于图像处理的函数&#xff0c;主要功能是将两个输入图像&#xff08;尺寸和类型相同&#xff09;按照指定的权重进行加权叠加&#xff08;图像融合&#xff09;&#xff0c;并添加一个标量值&#x…...

【算法训练营Day07】字符串part1

文章目录 反转字符串反转字符串II替换数字 反转字符串 题目链接&#xff1a;344. 反转字符串 双指针法&#xff0c;两个指针的元素直接调转即可 class Solution {public void reverseString(char[] s) {int head 0;int end s.length - 1;while(head < end) {char temp …...

【git】把本地更改提交远程新分支feature_g

创建并切换新分支 git checkout -b feature_g 添加并提交更改 git add . git commit -m “实现图片上传功能” 推送到远程 git push -u origin feature_g...

uniapp手机号一键登录保姆级教程(包含前端和后端)

目录 前置条件创建uniapp项目并关联uniClound云空间开启一键登录模块并开通一键登录服务编写云函数并上传部署获取手机号流程(第一种) 前端直接调用云函数获取手机号&#xff08;第三种&#xff09;后台调用云函数获取手机号 错误码常见问题 前置条件 手机安装有sim卡手机开启…...

【Android】Android 开发 ADB 常用指令

查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...

比较数据迁移后MySQL数据库和OceanBase数据仓库中的表

设计一个MySQL数据库和OceanBase数据仓库的表数据比较的详细程序流程,两张表是相同的结构,都有整型主键id字段,需要每次从数据库分批取得2000条数据,用于比较,比较操作的同时可以再取2000条数据,等上一次比较完成之后,开始比较,直到比较完所有的数据。比较操作需要比较…...

MySQL 主从同步异常处理

阅读原文&#xff1a;https://www.xiaozaoshu.top/articles/mysql-m-s-update-pk MySQL 做双主&#xff0c;遇到的这个错误&#xff1a; Could not execute Update_rows event on table ... Error_code: 1032是 MySQL 主从复制时的经典错误之一&#xff0c;通常表示&#xff…...

Vue3中的computer和watch

computed的写法 在页面中 <div>{{ calcNumber }}</div>script中 写法1 常用 import { computed, ref } from vue; let price ref(100);const priceAdd () > { //函数方法 price 1price.value ; }//计算属性 let calcNumber computed(() > {return ${p…...

图解JavaScript原型:原型链及其分析 | JavaScript图解

​​ 忽略该图的细节&#xff08;如内存地址值没有用二进制&#xff09; 以下是对该图进一步的理解和总结 1. JS 对象概念的辨析 对象是什么&#xff1a;保存在堆中一块区域&#xff0c;同时在栈中有一块区域保存其在堆中的地址&#xff08;也就是我们通常说的该变量指向谁&…...