【SringBoot项目中MyBatis-Plus多数据源应用实践】
文章目录
前言
一、Mybatis-Plus是什么?
二、多数据源是什么?
三、使用步骤
1. 新建一个SpringBoot项目
2. 引入必要的MyBatis架包
3. 新建两个数据库及两张表
3.3.1 新建数据库:DB_A,并创建一张数据表alarm_kind,以及一些测试数据。
3.3.2 同样再建一个数据库DB_B,并创建一张数据表test,以及一些测试数据。
4. 修改配置文件application.yml
5. 编码
5.1 entity 实体类
5.2 mapper接口
5.3 service服务接口
5.4 service服务实现
6. 测试及验证
总结
前言
在日常大型项目中经常会遇到分库分表的数据库设计,咱们普通的SpringBoot 单体项目通过默认配置及注解可以很容易实现对单个数据库的操作管理,但遇到需要多个数据库操作可能会比较麻烦,因此咱们今天主要介绍如何使用MyBatis-Plus提供的一个多数据源动态加载组件简单轻松实现在单个项目中实现对多个数据库的操作管理。
关键词:SpringBoot 、MyBatis、MyBatis-Plus、多数据源
一、Mybatis-Plus是什么?
Mybatis-Plus是一个Mybatis(opens new window)的增强工具,在Mybatis的基础上只做增强不做改变,为简化开发。
二、多数据源是什么?
多数据源是指在分布式环境或集群环境下,为不同的数据库(如MySQL、Oracle、SQLServer等)配置数据源,以便在项目中能够随意切换以获取数据。这种配置方式允许应用程序根据需要连接到不同的数据库,以实现特定的业务需求,如数据隔离、水平扩展、读写分离等。
三、使用步骤
1. 新建一个SpringBoot项目
可以通过Ide工具向导建立,这里不详细描述了。
2. 引入必要的MyBatis架包
在项目的pom.xml加入如何内容
<!-- mysql --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.18</version></dependency><!-- 连接池 --><dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-starter</artifactId><version>1.1.24</version></dependency><!-- mybatis plus --><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>${mybatisplus-spring-boot-starter.version}</version></dependency><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus</artifactId><version>>3.4.2</version></dependency><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-generator</artifactId><version>3.4.1</version></dependency><dependency><groupId>org.apache.velocity</groupId><artifactId>velocity-engine-core</artifactId><version>2.3</version></dependency><dependency><groupId>com.baomidou</groupId><artifactId>dynamic-datasource-spring-boot-starter</artifactId><version>3.5.0</version></dependency>
3. 新建两个数据库及两张表
3.3.1 新建数据库:DB_A,并创建一张数据表alarm_kind,以及一些测试数据。
CREATE DATABASE IF NOT EXISTS `DB_A` /*!40100 DEFAULT CHARACTER SET utf8mb4 */;
USE `DB_A`;DROP TABLE IF EXISTS `alarm_kind`;
CREATE TABLE IF NOT EXISTS `alarm_kind` (`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',`type_no` varchar(255) DEFAULT NULL COMMENT '类型编号',`type_name` varchar(255) DEFAULT NULL COMMENT '类型名称',PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=23 DEFAULT CHARSET=utf8mb4 COMMENT='报警类型字典表';DELETE FROM `alarm_kind`;
INSERT INTO `alarm_kind` (`id`, `type_no`, `type_name`) VALUES(1, 'Powon', '市电'),(2, 'Baton', 'UPS电源'),(3, 'Move', '位移'),(4, 'Alarm', '震动'),(5, 'Cut', '切割检测'),(6, 'Smoke', '烟雾'),(7, 'LBJ', '声光'),(8, 'HW', '红外'),(9, 'Box4_NoPutTimeOut', '四号柜款箱未放入');
3.3.2 同样再建一个数据库DB_B,并创建一张数据表test,以及一些测试数据。
CREATE DATABASE IF NOT EXISTS `DB_B` /*!40100 DEFAULT CHARACTER SET utf8mb4 */;
USE `DB_B`;DROP TABLE IF EXISTS `test`;
CREATE TABLE IF NOT EXISTS `alarm_kind` (`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',`type_no` varchar(255) DEFAULT NULL COMMENT '类型编号',`type_name` varchar(255) DEFAULT NULL COMMENT '类型名称',PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=23 DEFAULT CHARSET=utf8mb4 COMMENT='报警类型字典表';DELETE FROM `test`;
INSERT INTO `test` (`id`, `type_no`, `type_name`) VALUES(1, 'Powon', '测试1'),(2, 'Baton', '测试2'),(3, 'Move', '测试3');
4. 修改配置文件application.yml
server:port: 8085 #服务端口配置
spring:application:name: ms-basedatasource:dynamic:primary: baseA #默认加载的数据库是DB_Astrict: falsedatasource:baseA:driver-class-name: com.mysql.cj.jdbc.Driver #数据源配置url: jdbc:mysql://127.0.0.1:13306/DB_A?serverTimezone=GMT%2B8&useSSL=falseusername: rootpassword: data@123456!type: com.alibaba.druid.pool.DruidDataSource #连接池配置max-idle: 10 #No operations allowed after connection closed错误原因及解决max-wait: 10000min-idle: 5initial-size: 5validation-query: SELECT 1test-on-borrow: falsetest-while-idle: truetime-between-eviction-runs-millis: 18800baseB:driver-class-name: com.mysql.cj.jdbc.Driver #数据源配置url: jdbc:mysql:///127.0.0.1:13306/DB_B?serverTimezone=GMT%2B8&useSSL=falseusername: rootpassword: data@123456!type: com.alibaba.druid.pool.DruidDataSource #连接池配置max-idle: 10 #No operations allowed after connection closed错误原因及解决max-wait: 10000min-idle: 5initial-size: 5validation-query: SELECT 1test-on-borrow: falsetest-while-idle: truetime-between-eviction-runs-millis: 18800
5. 编码
5.1 entity 实体类
AlarmKind.java
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import java.time.LocalDateTime;
import java.io.Serializable;import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;/*** <p>* 报警类型字典表* </p>** @since 2022-05-24*/
@Data
@EqualsAndHashCode(callSuper = false)
public class AlarmKind implements Serializable {private static final long serialVersionUID = 1L;/*** 主键ID*/@TableId(value = "id", type = IdType.AUTO)private Long id;/*** 类型编号*/private String typeNo;/*** 类型名称*/private String typeName;
}
Test.java
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import java.time.LocalDateTime;
import java.io.Serializable;import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;/*** <p>* 测试表* </p>**/
@Data
@EqualsAndHashCode(callSuper = false)
public class Test implements Serializable {private static final long serialVersionUID = 1L;/*** 主键ID*/@TableId(value = "id", type = IdType.AUTO)private Long id;/*** 类型编号*/private String typeNo;/*** 类型名称*/private String typeName;
}
5.2 mapper接口
AlarmKIndMapper.java
import com.xxxx.rest.entity.AlarmKind;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;/*** <p>* 报警类型字典表 Mapper 接口* </p>**/
public interface AlarmKindMapper extends BaseMapper<AlarmKind> {List<AlarmKind> getAll();
}
TestMapper.java
import com.xxxx.rest.entity.Test;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;/*** <p>* 测试表 Mapper 接口* </p>**/
public interface TestMapper extends BaseMapper<Test> {List<Test> getAll();
}
5.3 service服务接口
IAlarmKIndService.java
import com.xxx.rest.entity.AlarmKind;
import com.baomidou.mybatisplus.extension.service.IService;import com.xianban.rest.model.msbase.vo.platform.BaseLineVO;import java.util.List;/*** <p>* 报警类型表 服务类* </p>**/
public interface IAlarmKindService extends IService<AlarmKind> {List<AlarmKind> getAll();
}
ITestService.java
import com.xxx.rest.entity.Test;
import com.baomidou.mybatisplus.extension.service.IService;import com.xianban.rest.model.msbase.vo.platform.BaseLineVO;import java.util.List;/*** <p>*测试表 服务类* </p>**/
public interface ITestService extends IService<Test> {List<Test> getAll();
}
5.4 service服务实现
AlarmKindServiceImpl.java
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xxxx.rest.entity.AlarmKind;
import com.xxxx.rest.mapper.AlarmKindMapper;
import com.xxxx.rest.service.IAlarmKindService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;/*** <p>* 报警类型表 服务实现类* </p>**/
@Service
@DS("baseA") //这个注解是指定操作哪个数据源,如果没有这个注解则代表操作配置文件中的主数据源
public class AlarmKindServiceImpl extends ServiceImpl<AlarmKindMapper, AlarmKind> implements IAlarmKindService {@Resourceprivate AlarmKindMapper mapper;@Overridepublic List<AlarmKind> getAll() {QueryWrapper<AlarmKind> wrapper=new QueryWrapper();return mapper.selectList(wwapper);}
}
TestServiceImpl.java
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xxxx.rest.entity.Test;
import com.xxxx.rest.mapper.TestMapper;
import com.xxxx.rest.service.ITestService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;/*** <p>* 测试表 服务实现类* </p>**/
@Service
@DS("baseB") //这个注解是指定操作哪个数据源,如果没有这个注解则代表操作配置文件中的主数据源
public class TestServiceImpl extends ServiceImpl<TestMapper, Test> implements ITestService {@Resourceprivate TestMapper mapper;@Overridepublic List<Test> getAll() {QueryWrapper<Test> wrapper=new QueryWrapper();return mapper.selectList(wwapper);}
}
6. 测试及验证
编写测试Controller
@RestController
@RequestMapping("/test")
@CrossOrigin
@Api(tags = "手动测试接口管理")
public class TestController {@Resourceprivate IAlarmKindService alarmKindService;@Resourceprivate ITestService testService;//查询报警类型数据@GetMapping("/getAlarmKindList")public ResponseEntity<Object> getAlarmKindList(){
return getRespOk(alarmKindService.getAll());
}
//查询测试表数据@GetMapping("/getTestList")public ResponseEntity<Object> getTestList(){
return getRespOk(testService.getAll());
}protected ResponseEntity<Object> getRespOk(Object resData) {return new ResponseEntity<>(resData, HttpStatus.OK); }}
启动项目
在浏览器访问
1.报警类型信息接口地址:http://localhost:8085/test/getAlarmKindList,如果返回结果说明正确
2.测试信息接口地址:http://localhost:8085/test/getTestList,如果返回结果说明正确
总结
通过以上内容分析,其实关键就引入架包、修改配置文件、服务的实现类中增加@DS("配置文件中定义的数据源名称"),代码改动可以说非常小。
相关文章:

【SringBoot项目中MyBatis-Plus多数据源应用实践】
文章目录 前言 一、Mybatis-Plus是什么? 二、多数据源是什么? 三、使用步骤 1. 新建一个SpringBoot项目 2. 引入必要的MyBatis架包 3. 新建两个数据库及两张表 3.3.1 新建数据库:DB_A,并创建一张数据表alarm_kind,以及…...

Android 图表开发开源库 MPAndroidChart 使用总结
1. 引言 电视项目中需要一个折线图表示节电数据变化情况,类比 H5 来说,Android 中也应该有比较成熟的控件,经过调研后,发现 MPAndroidChart 功能比较强大,网上也有人说可能是目前 Android 开发最好用的一个三方库了&a…...

手机号脱敏
手机号脱敏 // 手机号脱敏subTelephone(telphone) {let result telphone.substr(0, 4) **** telphone.substr(8);return result;},...

java基础篇(1)
JDK是什么?有哪些内容组成?JDK是Java开发工具包 JVM虚拟机: Java程序运行的地方 核心类库: Java已经写好的东西,我们可以直接用开发工具: javac、java、jdb、jhat.. JRE是什么?有哪些内容组成? JRE是Java运行环境 JVM、核心类库、运行工具 JDK,JRE&…...

2022年全国职业院校技能大赛高职组“信息安全管理与评估”赛项第三阶段任务书
第三阶段竞赛项目试题 本文件为信息安全管理与评估项目竞赛-第三阶段试题。根据信息安全管理与评估项目技术文件要求,第三阶段为夺旗挑战CTF(网络安全渗透)。 本次比赛时间为180分钟。 介绍 夺旗挑战赛(CTF)的目标…...

微信小程序蓝牙连接部分Android14调用wx.setBLEMTU协商低功耗最大传输单元失败解决方案(部分安卓14设置超过23就会报错)
1.解决方案的核心内容:第一次设置失败不要管,在complate函数里面继续往下连接,然后设置一个定时器每1秒钟在重新设置一次,肯定会成功的!!!!!!!&am…...

PDF格式分析(八十二)——电影注释(movie)
电影注释(PDF1.2及其以上版本),该注释包含图像和声音,声音通过扬声器进行播放,图像则显示在计算机屏幕上,如同一个视频播放器一样。当该类型注释被激活时,视频将被播放。 下表将显示电影注释的字典条目: 条…...

Opentracing 代码Demo
背景 OpenTracing 是一个提供标准化分布式追踪功能的API和工具。它的主要作用包括: 跨系统边界追踪请求流程:OpenTracing 允许开发者跟踪一个请求从开始到结束在整个分布式系统中的所有经过的点(包括异构系统),帮助理解系统中的请求流程和服务间的相互依赖。 性能分析和瓶…...

笔记93:关于 C++ 中的 Eigen 库
注意1:Eigen 是一个基于 C 模板的线性代数库,以支持在 C 中进行矩阵运算; 注意2:要在 C 中使用 Eigen,需要在在程序开始前要包含所需头文件路径; #include <Eigen> a a 基础用法汇总 定义向量 E…...

【微服务】部署mysql集群,主从复制,读写分离
两台服务器做如下操作 1.安装mysqldocker pull mysql:5.72.启动以及数据挂载 mkdir /root/mysql/data /root/mysql/log /root/mysql/conf touch my.conf //mysql的配置文件docker run --name mysql \ -e MYSQL_ROOT_PASSWORD123456 \ -v /root/mysql/data:/var/lib/mysql \ -v…...

【Java】设计一个支持敏感数据存储和传输安全的加解密平台
一、问题解析 在一个应用系统运行过程中,需要记录、传输很多数据,这些数据有的是非常敏感的,比如用户姓名、手机号码、密码、甚至信用卡号等等。这些数据如果直接存储在数据库,记录在日志中,或者在公网上传输的话&…...

iOS AVFoundation 音视频源码分享
引言 在现代移动开发中,音视频处理是一个不可忽视的重要领域。iOS 提供了强大的 AVFoundation 框架,使开发者能够轻松实现音视频录制、播放、编辑等功能。无论是创建高效的视频播放器,还是实现复杂的音频处理,AVFoundation 都能提…...

Ubuntu开发入门之“制作Ubuntu rootfs根文件系统镜像“
Ubuntu开发入门之“制作Ubuntu rootfs根文件系统镜像” 问题描述解决方法1.首先从官网下载最基础的ubuntu base核心文件,ubuntu core.2.接下来就是制作一个基础功能的根文件系统3.修改可用源4.接下来就是挂载根文件系统,进行模拟安装应用5.根文件系统安装常用的工具和配置用户…...

基于FPGA的SystemVerilog练习
文章目录 一、认识SystemVerilogSystemVerilog的语言特性SystemVerilog的应用领域SystemVerilog的优势SystemVerilog的未来发展方向 二、流水灯代码流水灯部分testbench仿真文件 三、用systemVerilog实现超声波测距计时器测距部分led部分数码管部分采样部分顶层文件引脚绑定效果…...

【数据结构】详解堆的基本结构及其实现
文章目录 前言1.堆的相关概念1.1堆的概念1.2堆的分类1.2.1小根堆1.2.2大根堆 1.3堆的特点堆的实用场景 2.堆的实现2.1初始化2.2插入2.3堆的向上调整2.4删除2.5堆的向下调整2.6判空2.7获取堆顶元素2.8销毁 3.堆排序3.1实现3.2堆排序的时间复杂度问题 前言 在上一篇文章中&#…...

python无限弹窗的代码
一个简单的Python代码示例,用于在特定的时间间隔内显示一个简单的弹窗。这个代码使用了Python的tkinter库来创建一个简单的GUI窗口。 python import tkinter as tk import time def popup(): popup_window.deiconify() # 显示窗口 popup_window.wait_window() # 等…...

多线程新手村5--线程池
1.1 线程池是什么 线程诞生的意义是因为进程的创建/销毁开销太大,所以使用线程提高代码的执行效率;那如果想要进一步提升执行效率,该怎么办呢?有一个方法是使用线程池。 首先,什么是线程池:池就是池子&am…...

数据库 mysql 的彻底卸载
MySQL卸载步骤如下: (1)按 winr 快捷键,在弹出的窗口输入 services.msc,打开服务列表。 (2)在服务列表中, 找到 mysql 开头的所有服务, 右键停止,终止对应的…...

Meterpreter工具使用
Meterpreter属于stage payload,在Metasploit Framework中,Meterpreter是一种后渗透工具,它 属于一种在运行过程中可通过网络进行功能扩展的动态可扩展型Payload。这种工具是基于“内存DLL注 入”理念实现的,它能够通过创建一个新进…...

第四讲 单片机STC89C52+RA8889代码移植范例(包含API接口)
本次介绍单片机STC89C52RA8889代码移植范例,该范例已将RA8889的API移植好了,下方提供下载地址。 硬件平台:89C52RA8889 采用SPI通信方式 (已测试通过) 上一讲已经阐述RA8889移植到51单片机的基本方法,本讲增加了API…...

QT 音乐播放器【一】 显示音频级别指示器
文章目录 效果图概述代码总结 效果图 概述 QMediaPlayer就不介绍了,就提供了一个用于播放音频和视频的媒体播放器 QAudioProbe 它提供了一个探针,用于监控音频流。当音频流被捕获或播放时,QAudioProbe 可以接收到音频数据。这个类在需要访问…...

【MATLAB源码-第220期】基于matlab的Massive-MIMO误码率随着接收天线变化仿真采用ZF均衡和QPSK调制。
操作环境: MATLAB 2022a 1、算法描述 1. 系统背景与目标 无线通信系统的发展极大地推动了现代通信技术的进步,从移动通信到无线局域网,甚至是物联网,均依赖于无线通信系统的高效和可靠性。在无线通信系统中,核心目…...

【前端】政务服务大数据可视化监控平台(源码+html+css+js)
👉博__主👈:米码收割机 👉技__能👈:C/Python语言 👉公众号👈:测试开发自动化【获取源码商业合作】 👉荣__誉👈:阿里云博客专家博主、5…...

【网关】工业智能网关-02
一 公司简介 保定飞凌嵌入式技术有限公司始于2006年,是一家专注嵌入式核心控制系统研发、设计和生产的高新技术企业,是国内最早专业从事嵌入式技术的企业之一。 经过十几年的发展与积累,公司拥有业内一流的软硬件研发团队,在北京…...

【C语言】动态内存管理技术文档
【C语言】动态内存管理技术文档 目录 【C语言】动态内存管理技术文档 一、内存管理基础...

低空经济的意义所在
发展低空经济对于推动经济发展、促进产业升级、降低运输成本、构建综合交通系统等方面都具有重要意义。低空经济对推动经济发展提供新动能。低空经济作为新兴产业,具有巨大的发展潜力,能够带动投资、促进消费,为经济增长注入新动力。除此之外…...

DNF手游攻略:0氪攻略,转职技巧与避坑指南!
在DNF手游的冒险旅程中,角色的转职是一次重要的成长经历。通过转职,玩家可以获得全新的技能和属性,提升自己在地下城中的战斗力。本文将为您介绍转职后的关键技巧和日常任务,帮助您更好地适应新的职业身份,成为地下城中…...

周报 | 24.5.27-24.6.2文章汇总
为了更好地整理文章和发表接下来的文章,以后每周都汇总一份周报。 周报 | 24.5.20-24.5.26文章汇总-CSDN博客 集智书童 | YOLOv10开源|清华用端到端YOLOv10在速度精度上都生吃YOLOv8和YOLOv9_yolov8 yolov10-CSDN博客 机器之心 | 清华接手,…...

【C++初阶学习】第十二弹——stack和queue的介绍和使用
C语言栈:数据结构——栈(C语言版)-CSDN博客 C语言队列:数据结构——队列(C语言版)-CSDN博客 前言: 在之前学习C语言的时候,我们已经学习过栈与队列,并学习过如何使用C语言来实现栈与队列&…...

nginx反向代理了解
文章目录 Nginx反向代理反向代理系统调优Proxy Buffer相关指令 Nginx 具有高性能的http和反向代理的web服务器,同时也是一个pop3/smtp/imap代理服务器,使用c语言编写 **Web服务器:**也叫网页服务器,web server,主要功…...