实战指南,SpringBoot + Mybatis 如何对接多数据源

系列文章目录

MyBatis缓存原理
Mybatis plugin 的使用及原理
MyBatis+Springboot 启动到SQL执行全流程
数据库操作不再困难,MyBatis动态Sql标签解析
从零开始,手把手教你搭建Spring Boot后台工程并说明
Spring框架与SpringBoot的关联与区别
Spring监听器用法与原理详解
Spring事务畅谈 —— 由浅入深彻底弄懂 @Transactional注解



在这里插入图片描述
在我们开发一些具有综合功能的项目时,往往会碰到一种情况,需要同时连接多个数据库,这个时候就需要用到多数据源的设计。而Spring 与 Myabtis 其实做了多数据源的适配,只需少许改动即可对接多数据源。本期我们就贴近实战,以一个单数据源的Demo为例,讲述将其改为多数据源项目的过程,希望大家能有所体会

📕作者简介:战斧,从事金融IT行业,有着多年一线开发、架构经验;爱好广泛,乐于分享,致力于创作更多高质量内容
📗本文收录于 Spring全家桶 专栏,有需要者,可直接订阅专栏实时获取更新
📘高质量专栏 云原生、RabbitMQ、Spring全家桶 等仍在更新,欢迎指导
📙Zookeeper Redis kafka docker netty等诸多框架,以及架构与分布式专题即将上线,敬请期待


一、数据源的定义

数据源(Data Source)是指数据存储的地方,大多数情况是指数据库,不过文件服务器、传感器、API等也能算数据源,主要是提供了对数据的访问和操作。数据源中存储了所有建立数据库连接的信息。就像通过指定文件名称可以在文件系统中找到文件一样,通过提供正确的数据源名称,你可以找到相应的数据库连接
在这里插入图片描述

二、单数据源配置

因为SpringBoot对数据源有着高度的默认配置,只配置一个数据源时,该数据源会被作为默认,所以对接单数据源其实是非常简单的。如果你的工程采用的yaml格式配置文件,我们仅需做如下配置:

spring:#数据库连接配置datasource:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://127.0.0.1:3306/springtestusername: rootpassword: root

如果是采用properties配置文件的也是一样的:

spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/springtest
spring.datasource.username=root
spring.datasource.password=root

三、如何配置多数据源

1. 工程层级调整

我们以曾经搭建的工程为原始模板,进行对接多数据源的操作。没看过的可以点此查看: 从零开始,手把手教你搭建Spring Boot后台工程并说明
在这里插入图片描述
因为仅变动数据源,所以我们不改动其他层级,仅仅将 mapper 拆为 mapper1mapper2 两部分
在这里插入图片描述

2. Spring项目配置

然后我们需要在 application.properties 或者 application.yml 中定义多个数据源:

spring:#数据库连接配置datasource1:driver-class-name: com.mysql.cj.jdbc.Driverjdbc-url: jdbc:mysql://127.0.0.1:3306/springtest2username: rootpassword: rootdatasource2:driver-class-name: com.mysql.cj.jdbc.Driverjdbc-url: jdbc:mysql://127.0.0.1:3306/springtestusername: rootpassword: root

这里有两个细节需要注意:

  1. 因为我们决定使用双数据源,所以把数据源的连接配置改成了datasource1datasource2。而不再保留datasource,这样SpringBoot就不再会为我们设定默认数据库
  2. 因为我们目前采用的 springBoot2.5.2,默认的连接池为Hikari,该连接池数据源的地址字段为jdbc-url 而非 url。在只有单个数据源时,SpringBoot走默认数据源逻辑为我们把 urljdbc-url 进行映射,保证我们获得数据源。此时我们自己设置的数据源没有进行映射处理,就需要保证字段符合Hikari的要求。否则会出现 java.lang.IllegalArgumentException: jdbcUrl is required with driverClassName 异常

3. 会话配置

仅有配置文件可不行,接下来,我们需要在代码中读取到配置,并建立两个数据源。如下,每个数据源都有隔离的mapper接口、xml文件、会话工厂及会话模板

第一个数据源 如下(示例):

@Configuration
@MapperScan(basePackages = "com.zhanfu.springboot.demo.mapper1", sqlSessionFactoryRef = "sqlSessionFactory1")
public class DataSource1Config {@Bean@ConfigurationProperties(prefix = "spring.datasource1")public DataSource dataSource1() {return DataSourceBuilder.create().build();}@Beanpublic SqlSessionFactory sqlSessionFactory1() throws Exception {SqlSessionFactoryBean sessionFactoryBean = new SqlSessionFactoryBean();sessionFactoryBean.setDataSource(dataSource1());String locationPattern = "classpath*:/mapper1/*.xml";PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();sessionFactoryBean.setMapperLocations(resolver.getResources(locationPattern));return sessionFactoryBean.getObject();}@Bean(name = "sqlSessionTemplate1")public SqlSessionTemplate sqlSessionTemplate1(@Qualifier("sqlSessionFactory1") SqlSessionFactory sqlSessionFactory) {return new SqlSessionTemplate(sqlSessionFactory);}
}

配置第二个数据源 DataSource2Config

@Configuration
@MapperScan(basePackages = "com.zhanfu.springboot.demo.mapper2", sqlSessionFactoryRef = "sqlSessionFactory2")
public class DataSource2Config {@Bean@ConfigurationProperties(prefix = "spring.datasource2")public DataSource dataSource2() {return DataSourceBuilder.create().build();}@Beanpublic SqlSessionFactory sqlSessionFactory2() throws Exception {SqlSessionFactoryBean sessionFactoryBean = new SqlSessionFactoryBean();sessionFactoryBean.setDataSource(dataSource2());String locationPattern = "classpath*:/mapper2/*.xml";PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();sessionFactoryBean.setMapperLocations(resolver.getResources(locationPattern));return sessionFactoryBean.getObject();}@Bean(name = "sqlSessionTemplate2")public SqlSessionTemplate sqlSessionTemplate2(@Qualifier("sqlSessionFactory2") SqlSessionFactory sqlSessionFactory) {return new SqlSessionTemplate(sqlSessionFactory);}@Bean(name = "productMapper")public ProductMapper mapper2(@Qualifier("sqlSessionTemplate2") SqlSessionTemplate sqlSessionTemplate) throws Exception {return sqlSessionTemplate.getMapper(ProductMapper.class);}
}

4. 事务管理器

为两个数据源分别配置自己的事务管理器,如果你的项目里通篇没有方法级别的事务(一个SQL就是一个事务),那不设置这个也不影响,否则还是建议加上。

@Configuration
public class TransactionManagerConfig {@Autowiredprivate DataSource dataSource1;@Autowiredprivate DataSource dataSource2;@Beanpublic PlatformTransactionManager txManager1() {return new DataSourceTransactionManager(dataSource1);}@Beanpublic PlatformTransactionManager txManager2() {return new DataSourceTransactionManager(dataSource2);}
}

四、验证

我们把两张表拆进两个库中,以两个库模拟两个数据源,使得程序可以同时连接两个库
在这里插入图片描述
浏览器输入 http://127.0.0.1:8080/user/findall 查询接口成功
在这里插入图片描述
再在浏览器输入 http://127.0.0.1:8080/product/findall 查询第二个库的数据亦成功返回
在这里插入图片描述
这样我们就完成了一个工程同时连接两个数据源。


总结

经过上述的操作,我们已经成功把项目对接了多数据源。当然,方案肯定不止这一种,后续围绕该问题,我们还会讲解其他方式。但不论是什么方式,主旨都是加深大家对SpringBoot 和 Mybatis的理解,我们曾经梳理过全流程,但只是蜻蜓点水带大家看一遍大体轮廓,并不足以让你精通,后面本专栏将继续深入讲解

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

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

相关文章

基于eBPF技术构建一种应用层网络管控解决方案

引言 随着网络应用的不断发展,在linux系统中对应用层网络管控的需求也日益增加,而传统的iptables、firewalld等工具难以针对应用层进行网络管控。因此需要一种创新的解决方案来提升网络应用的可管理性。 本文将探讨如何使用eBPF技术构建一种应用层网络…

【CSS】禁用元素鼠标事件(例如实现元素禁用效果)

文章目录 基本用法 基本用法 pointer-events 属性指定在什么情况下 (如果有) 某个特定的图形元素可以成为鼠标事件。实际运用中可以通过对auto 和none动态控制,来动态实现元素的禁用效果。 属性描述auto与pointer-events属性未指定时的表现效果相同,对…

【笔试题心得】排序算法总结整理

排序算法汇总 常用十大排序算法_calm_G的博客-CSDN博客 以下动图参考 十大经典排序算法 Python 版实现(附动图演示) - 知乎 冒泡排序 排序过程如下图所示: 比较相邻的元素。如果第一个比第二个大,就交换他们两个。对每一对相邻…

【LeetCode-简单】剑指 Offer 29. 顺时针打印矩阵(详解)

题目 输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字。 示例 1: 输入:matrix [[1,2,3],[4,5,6],[7,8,9]] 输出:[1,2,3,6,9,8,7,4,5]示例 2: 输入:matrix [[1,2,3,4],[5,6,7,8],[9,10,1…

互联网发展历程:速度与效率,交换机的登场

互联网的演进就像一场追求速度与效率的竞赛,每一次的技术升级都为我们带来更快、更高效的网络体验。然而,在网络的初期阶段,人们面临着数据传输速度不够快的问题。一项关键的技术应运而生,那就是“交换机”。 速度不足的困境&…

规划性和可扩展性,助力企业全面预算管理的推进

对于当今社会经济市场的不稳定状况和不断变化的消费者行为,企业业务也从未像今天这样不可预测过。面对变化和变革,企业需要具备规划性的预测能力,才能使得自身在竞争中保持领先地位。那些具备前瞻性的企业都尝试在现阶段通过更好的规划不断提…

基于Mysqlrouter+MHA+keepalived实现高可用半同步 MySQL Cluster项目

目录 项目名称: 基于Mysqlrouter MHA keepalived实现半同步主从复制MySQL Cluster MySQL Cluster: 项目架构图: 项目环境: 项目环境安装包: 项目描述: 项目IP地址规划: 项目步骤: 一…

windows11下配置vscode中c/c++环境

本文默认已经下载且安装好vscode,主要是解决环境变量配置以及编译task、launch文件的问题。 自己尝试过许多博客,最后还是通过这种方法配置成功了。 Linux(ubuntu 20.04)配置vscode可以直接跳转到配置task、launch文件,不需要下载mingw与配…

localhost:8080 is already in use

报错原因:本机的8080端口号已经被占用。因为机器的空闲端口号是随机分配的,而idea默认启动的端口号是8080,所以是存在这种情况。 对于这个问题,我们只需要重启idea或者修改项目的启动端口号即可。 更推荐第二种。对于修改项目启动端口号&…

ZDH-wemock模块

本次介绍基于版本v5.1.1 目录 项目源码 预览地址 安装包下载地址 wemock模块 wemock模块前端 配置首页 配置mock wemock服务 下载地址 打包 运行 效果展示 项目源码 zdh_web: https://github.com/zhaoyachao/zdh_web zdh_mock: https://github.com/zhaoyachao/z…

TCGA数据下载推荐:R语言easyTCGA包

#使用easyTCGA获取数据 #清空 rm(listls()) gc() # 安装bioconductor上面的R包 options(BioC_mirror"https://mirrors.tuna.tsinghua.edu.cn/bioconductor") if(!require("BiocManager")) install.packages("BiocManager") if(!require("TC…

怎样让音频速度变慢?请跟随以下方法进行操作

怎样让音频速度变慢?在会议录音过程中,经常会遇到主讲人语速过快,导致我们无法清晰听到对方说的内容。如果我们能够减慢音频速度,就能更好地记录对方的讲话内容。此外,在听到快速播放的外语或方言时,我们也…

机器人的运动范围

声明 该系列文章仅仅展示个人的解题思路和分析过程,并非一定是优质题解,重要的是通过分析和解决问题能让我们逐渐熟练和成长,从新手到大佬离不开一个磨练的过程,加油! 原题链接 机器人的运动范围https://leetcode.c…

高等数学教材重难点题型总结(二)导数与微分

本章重点题目较少,除了*标题页没什么特别难的,本帖出于总结性的角度考虑并未囊概全部的*标,最后会出一期*标题的全部内容整理,在攻克重难点的基础上更上一层楼。 1.根据定义求某点处的导数值 2.通过定义证明导数 3.左右导数的相关…

【数据库】P4 过滤数据 WHERE

过滤数据 WHERE 简介WHERE 子句操作符检测单个值案例范围值检查 BETWEEN AND空值检查 NULL 简介 数据库表一般包含大量的数据,很少需要检索表中的所有行。我们只检索所需数据需要指定搜索条件(search criteria),搜索条件也称为过滤条件(filter conditio…

完全备份、增量备份、差异备份、binlog日志

Top NSD DBA DAY06 案例1:完全备份与恢复案例2:增量备份与恢复案例3:差异备份与恢复案例4:binlog日志 1 案例1:完全备份与恢复 1.1 问题 练习物理备份与恢复练习mysqldump备份与恢复 1.2 方案 在数据库服务器192…

问AI一个严肃的问题

chatgpt的问世再一次掀起了AI的浪潮,其实我一直在想,AI和人类的关系未来会怎样发展,我们未来会怎样和AI相处,AI真的会完全取代人类吗,带着这个问题,我问了下chatgpt,看一看它是怎么看待这个问题…

Modbus工业RFID设备在自动化生产线中的应用

传统半自动化生产线在运作的过程,因为技工的熟练程度,专业素养的不同,在制造过程中过多的人为干预,工厂将很难对每条生产线的产能进行标准化管理和优化。如果半自动化生产线系统是通过前道工序的作业结果和检测结果来决定产品在下…

react实现模拟弹框遮罩的自定义hook

需求描述 点击按钮用于检测鼠标是否命中按钮 代码实现 import React from react; import {useState, useEffect, useRef} from react;// 封装一个hook用来检测当前点击事件是否在某个元素之外 function useClickOutSide(ref,cb) {useEffect(()>{const handleClickOutside…

JMeter接口自动化测试实例—JMeter引用javaScript

Jmeter提供了JSR223 PreProcessor前置处理器,通过该工具融合了Java 8 Nashorn 脚本引擎,可以执行js脚本以便对脚本进行前置处理。其中比较典型的应用就是通过执行js脚本对前端数据进行rsa加密,如登录密码加密。但在这里我就简单的应用javaScr…