【SpringBoot】11 多数据源(MyBatis:dynamic-datasource)

介绍

多数据源:指的是一个单一应用程序中涉及了两个及以上的数据库,这种配置允许应用程序根据业务需求灵活地管理和操作不同的数据库。

需求

一个应用服务中,连接多个数据库,有本地的也有远程的,有MysQL、Oracle、PostgreSQL(按需配置,可以配置同样的数据源,也可以配置不用的数据源)。

依赖

pom.xml

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

效果图

项目启动时,载入的三个数据源。
在这里插入图片描述在这里插入图片描述
用户接口(wx数据库)
在这里插入图片描述
角色接口(alipay数据库)
在这里插入图片描述
权限接口(oct数据库)
在这里插入图片描述

代码实现

配置文件中连接了三个数据库,wx数据库是MySQL,alipay数据库是Oracle,oct数据库是PostgreSQL。wx数据库是在本地,alipay数据库和oct数据库是在远程,可以按需配置。
注:项目启动程序就会去创建与所有配置数据库之间的连接,如果连不上则会启动失败。

配置

application.yml

server:port: 8888spring:application:name: systemthymeleaf:prefix: classpath:/templates/ #前缀,默认为classpath:/templates/suffix: .html #后缀,默认为.html
#  单个数据库
#  datasource:
#    driver-class-name: com.mysql.cj.jdbc.Driver
#    url: jdbc:mysql://localhost:3306/system?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
#    username: root
#    password: root
# 多个数据库datasource:dynamic:
#      primary: master #默认主库strict: truedatasource:wx: #MySQLdriver-class-name: com.mysql.jdbc.Driverurl: jdbc:mysql://localhost:3306/wx?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8username: rootpassword: rootalipay: #Oracledriver-class-name: oracle.jdbc.OracleDriverurl: jdbc:oracle:thin:@remote:1521:sid #remote是对应机器服务器的远程地址,sid是具体的数据库实例
#          driver-class-name: com.mysql.jdbc.Driver
#          url: jdbc:mysql://localhost:3306/alipay?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8username: rootpassword: rootoct: #PostgreSQLdriver-class-name: org.postgresql.Driverurl: jdbc:postgresql://remote:5432/postgres #remote是对应机器服务器的远程地址
#          driver-class-name: com.mysql.jdbc.Driver
#          url: jdbc:mysql://localhost:3306/oct?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8username: rootpassword: rootmail:#    host: smtp.163.comhost: smtp.qq.comport: 465 #587#    username: xxx@163.comusername: xxx@qq.compassword: xxx #授权码default-encoding: UTF-8properties:mail:debug: truesmtp:socketFactory:class: javax.net.ssl.SSLSocketFactoryssl:enable: trueschedule:cron:  0/5 * * * * ?  #5s执行一次wxFlag: truealipayFlag: falseoctFlag: falselogging:config: classpath:log4j2.ymllevel:com.lm.system.mapper: debug

代码

所有的User相关的方法默认读取wx的MySQL数据库,只要在类上加上 @DS(“wx”) 注解。如果是接口中多个方法用到多个不同的数据源时,可在方法上加@DS(“wx”)注解,该注解是按就近原则进行加载。

User(wxDB)

UserMapper.java

@DS("wx")
public interface UserMapper {}

Role(alipayDB)

Role.java

package com.lm.system.common;import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;import java.util.Date;/*** @author DUHAOLIN* @date 2024/8/21*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Role {@TableId(value = "role_id", type = IdType.INPUT)private Integer roleId; //自增长private String roleName;private String description;private Integer status; //可用状态,0不可用,1可用private Date createTime;private Date updateTime;}

RoleMapper.java

package com.lm.system.mapper;import com.baomidou.dynamic.datasource.annotation.DS;
import com.lm.system.common.Role;import java.util.List;/*** @author DUHAOLIN* @date 2024/8/21*/
@DS("alipay")
public interface RoleMapper {List<Role> queryRoles();}

RoleMapper.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.lm.system.mapper.RoleMapper"><resultMap id="beans" type="com.lm.system.common.Role"><id property="roleId" column="role_id" jdbcType="INTEGER" /><result property="roleName" column="role_name" jdbcType="VARCHAR" /><result property="status" column="status" jdbcType="INTEGER" /><result property="description" column="description" jdbcType="VARCHAR" /><result property="createTime" column="create_time" jdbcType="DATE" /><result property="updateTime" column="update_time" jdbcType="DATE" /></resultMap><select id="queryRoles" resultMap="beans">SELECT * FROM T_ROLE</select></mapper>

RoleController.java

package com.lm.system.controller;import com.lm.system.common.ResultBody;
import com.lm.system.common.Role;
import com.lm.system.mapper.RoleMapper;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import javax.annotation.Resource;
import java.util.List;/*** @author DUHAOLIN* @date 2024/8/21*/
@RestController
@Api(tags = "角色接口")
@RequestMapping("role")
public class RoleController {@Resourceprivate RoleMapper roleMapper;@GetMapping("query")@ApiOperation("获取角色信息")public String queryRoles() {List<Role> roles = roleMapper.queryRoles();return ResultBody.build(roles == null ? HttpStatus.NO_CONTENT : HttpStatus.OK).setData(roles).setCount(roles == null ? 0 : 1).getReturn();}}

Permission(octDB)

Permission.java

package com.lm.system.common;import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;import java.util.Date;/*** @author DUHAOLIN* @date 2024/8/21*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Permission {@TableId(value = "permission_id", type = IdType.INPUT)private Integer permissionId; //自增长private String permissionName;private String description;private Date createTime;private Date updateTime;}

PermissionMapper.java

package com.lm.system.mapper;import com.baomidou.dynamic.datasource.annotation.DS;
import com.lm.system.common.Permission;import java.util.List;/*** @author DUHAOLIN* @date 2024/8/21*/
public interface PermissionMapper {@DS("oct")List<Permission> queryPermissions();}

Permission.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.lm.system.mapper.PermissionMapper"><resultMap id="beans" type="com.lm.system.common.Permission"><id property="permissionId" column="permission_id" jdbcType="INTEGER" /><result property="permissionName" column="permission_name" jdbcType="VARCHAR" /><result property="description" column="description" jdbcType="VARCHAR" /><result property="createTime" column="create_time" jdbcType="DATE" /><result property="updateTime" column="update_time" jdbcType="DATE" /></resultMap><select id="queryPermissions" resultMap="beans">SELECT * FROM T_PERMISSION</select></mapper>

PermissionController.java

package com.lm.system.controller;import com.lm.system.common.Permission;
import com.lm.system.common.ResultBody;
import com.lm.system.mapper.PermissionMapper;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import javax.annotation.Resource;
import java.util.List;/*** @author DUHAOLIN* @date 2024/8/21*/
@RestController
@Api(tags = "权限接口")
@RequestMapping("permission")
public class PermissionController {@Resourceprivate PermissionMapper permissionMapper;@GetMapping("query")@ApiOperation("获取权限信息")public String queryPermission() {List<Permission> permissions = permissionMapper.queryPermissions();return ResultBody.build(permissions == null ? HttpStatus.NO_CONTENT : HttpStatus.OK).setData(permissions).setCount(permissions == null ? 0 : 1).getReturn();}}

SQL

t_user.sql

/*Navicat Premium Data TransferSource Server         : localhostSource Server Type    : MySQLSource Server Version : 50734Source Host           : localhost:3306Source Schema         : wxTarget Server Type    : MySQLTarget Server Version : 50734File Encoding         : 65001Date: 21/08/2024 16:49:21
*/SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;-- ----------------------------
-- Table structure for t_user
-- ----------------------------
DROP TABLE IF EXISTS `t_user`;
CREATE TABLE `t_user`  (`id` int(11) NOT NULL AUTO_INCREMENT,`name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,`age` int(11) NULL DEFAULT NULL,`gender` varchar(2) NOT NULL COMMENT ,`deleted` tinyint(1) NOT NULL COMMENT '0未删除,1已删除',`create_time` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0),`update_time` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0),PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 4 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;-- ----------------------------
-- Records of t_user
-- ----------------------------
INSERT INTO `t_user` VALUES (1, 'Tom', 18, '男', 0, '2024-08-21 16:47:45', '2024-08-21 16:47:45');
INSERT INTO `t_user` VALUES (2, 'Joe', 20, '女', 0, '2024-08-21 16:47:58', '2024-08-21 16:47:58');
INSERT INTO `t_user` VALUES (3, 'Jim', 33, '女', 0, '2024-08-21 16:48:12', '2024-08-21 16:48:12');SET FOREIGN_KEY_CHECKS = 1;

t_role.sql

--------------------------------------------------------
--  文件已创建 - 星期三-八月-21-2024   
--------------------------------------------------------
--------------------------------------------------------
--  DDL for Table T_ROLE
--------------------------------------------------------SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;-- ----------------------------
-- Table structure for T_ROLE
-- ----------------------------
DROP TABLE IF EXISTS `T_ROLE`;
CREATE TABLE `T_ROLE`  (`ROLE_ID` int(11) NOT NULL AUTO_INCREMENT,`ROLE_NAME` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,`DESCRIPTION` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,`STATUS` tinyint(1) NOT NULL COMMENT '可用状态,0不可用,1可用',`CREATE_TIME` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0),`UPDATE_TIME` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0),PRIMARY KEY (`ROLE_ID`) USING BTREE
);-- ----------------------------
-- Records of T_ROLE
-- ----------------------------
INSERT INTO `T_ROLE` VALUES (-1, '管理员', '拥有所有权限', 1, '2024-08-21 17:04:01', '2024-08-21 17:04:01');
INSERT INTO `T_ROLE` VALUES (1, '财务', '拥有查看和操作权限', 1, '2024-08-21 17:04:14', '2024-08-21 17:04:14');
INSERT INTO `T_ROLE` VALUES (2, '观察员', '拥有查看的账号', 1, '2024-08-21 17:05:19', '2024-08-21 17:05:19');SET FOREIGN_KEY_CHECKS = 1;

t_permission.sql

/*Navicat Premium Data TransferSource Server         : octSource Server Type    : PostgreSQLSource Server Version : 120001Source Host           : remote:portSource Catalog        : octSource Schema         : publicTarget Server Type    : PostgreSQLTarget Server Version : 120001File Encoding         : 65001Date: 21/08/2024 16:53:21
*/-- ----------------------------
-- Table structure for t_permission
-- ----------------------------
DROP TABLE IF EXISTS "public"."t_permission";
CREATE TABLE "public"."t_permission" ("permission_id" varchar(30) COLLATE "pg_catalog"."default" NOT NULL,"permission_name" varchar(30) COLLATE "pg_catalog"."default" NOT NULL,"description" varchar(150) COLLATE "pg_catalog"."default","create_time" timestamp(0) COLLATE "pg_catalog"."default" NOT NULL,"update_time" timestamp(0) COLLATE "pg_catalog"."default" NOT NULL
)
;-- ----------------------------
-- Records of oct
-- ----------------------------
INSERT INTO "public"."t_permission" VALUES (1, '用户管理', '管理用户账号', '2024-08-22 09:35:18', '2024-08-22 09:35:18');
INSERT INTO "public"."t_permission" VALUES (2, '角色管理', '管理用户角色', '2024-08-22 09:35:50',    '2024-08-22 09:35:50');
INSERT INTO "public"."t_permission" VALUES (3, '权限管理', '管理角色权限', '2024-08-22 09:36:05',    '2024-08-22 09:36:05');-- ----------------------------
-- Primary Key structure for table t_permission
-- ----------------------------
ALTER TABLE "public"."t_permission" ADD CONSTRAINT "t_permission_pk" PRIMARY KEY ("id", "option");

项目目录结构图

在这里插入图片描述

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

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

相关文章

前端实现首次访问,后续从本地访问

在前端实现将PDF文件下载到用户的本地磁盘&#xff0c;并在后续加载时使用本地文件&#xff0c;而不是重新从服务器下载&#xff0c;可以通过以下步骤实现&#xff1a; 1. **使用<a>标签的download属性**&#xff1a;当用户首次点击下载PDF时&#xff0c;通过<a>标…

PDPS软件 那智机器人 (丰田版)离线程序导出处理

在PDPS仿真软件中导出的那智机器人离线程序&#xff0c;一般是无法直接给TFD控制装置-那智机器人&#xff08;丰田式样版&#xff09;导入及识别使用。因此要对导出的程序进行转换编译处理&#xff0c;才能给TFD那智机器人&#xff08;丰田式样版&#xff09;导入离线程序。以下…

C语言宏的深度探索与全面应用策略

C语言的宏机制是一种预处理器功能&#xff0c;它允许程序员在编译阶段进行文本替换&#xff0c;以实现代码的复用、条件编译和性能优化等目标。然而&#xff0c;宏的使用也伴随着一些挑战&#xff0c;如可能导致代码难以理解和维护、引入未预期的行为等。本文旨在深入剖析C语言…

react antd TreeSelect实现自定义标签

<ProFormTreeSelectlabel"接收对象"name"receiverObjects"colProps{{ span: 16 }}labelCol{{span: 6,}}wrapperCol{{span: 18,}}rules{[{ required: true }]}fieldProps{{showSearch: true,multiple: true,// autoClearSearchValue: true,filterTreeNod…

NASA:北极辐射-冰桥海冰实验(ARISE)2014年原地云数据产品

ARISE_Cloud_AircraftInSitu_C130_Data 简介 ARISE_Cloud_AircraftInSitu_C130_Data_1是北极辐射-冰桥海冰实验&#xff08;ARISE&#xff09;2014年原地云数据产品。该产品是位于华盛顿的美国宇航局科学任务局地球科学部辐射科学、冰冻层科学和机载科学计划共同努力的成果。…

基于单片机的一氧化碳报警系统的设计与实现

摘 要&#xff1a; 一氧化碳对人体有害&#xff0c;尤其超标时会影响人们的健康 。 因此文章设计了一款基于单片机的一氧化氮报警器设计。 论文通过传感器检测一氧化碳浓度&#xff0c;经过 AD 转换&#xff0c;再把检测信号传递给单片机&#xff0c;经过分析处理&#xff0c…

论文辅助笔记:Large Language Models are Zero-Shot Next LocationPredictors

论文理论部分&#xff1a;论文笔记&#xff1a;lunLarge Language Models are Zero-Shot Next LocationPredictors-CSDN博客 2 Data 2.1 Dataset类 2.2 下载文件 2.3 get_dataset 2.4 get_trajectories trajectory_split暂时略去 # save the test dictionary and the true l…

redis核心数据结构源码分析

dictEntry和redisObject 在 Redis 的实现中&#xff0c;当一个键值对被创建并存储时&#xff0c;键通常是一个字符串&#xff0c;而值则是一个 redisObject。因此&#xff0c;在 dictEntry 结构中&#xff0c;key 成员指向的是一个字符串&#xff0c;而 v.val 成员则指向一个 …

ChatGPT 3.5/4.0简单使用手册

ChatGPT 3.5/4.0 是一种先进的人工智能聊天机器人&#xff0c;能够理解和生成自然语言文本&#xff0c;为用户提供信息检索、问题解答、语言翻译等服务。 系统要求 操作系统&#xff1a;无特定要求&#xff0c;支持主流操作系统。网络连接&#xff1a;需要稳定的网络连接来使…

45.5【C语言】typedef

目录&#xff1a; *全称 *格式 一般指针 数组指针 函数指针 *细节 *全称 type define 类型&#xff08;重新&#xff09;定义&#xff08;或命名&#xff09;&#xff0c;可简化输入 *格式 1.非指针类型: typedef 类型 简化名称 typedef signed long long k; signed long …

期末九天从入门到精通操作数据库(mysql)

对应资源包名称&#xff1a; 期末九天从入门到精通操作数据库(mysql) 学习目标&#xff1a; 掌握数据库的基本操作&#xff0c;熟练使用navicat工具. 九天极限掌握数据库 学习内容&#xff1a; 数据查询实验视图管理实验索引管理实验用户安全性管理实验MySQL备份和还原实…

搭建自己的金融数据源和量化分析平台(七):定时更新上市公司所属行业门类及大类

0x00 前言 由于此前从深交所下载的股票信息中只有行业门类信息&#xff0c;没有行业大类信息&#xff0c;导致后续解析三大报表和量化选股的时候无法进行&#xff1a; 可以看到深交所的股票是没有大类信息的。 再看看上交所的保险股&#xff1a; 因此需要将深交所股票的所属…

WIFI驱动开发

Linux 4.9 内核驱动移植 Linux 4.9 BSP 内核驱动 下载驱动后获得驱动的 tar.gz 压缩包 解压后找到如下驱动与文件夹 进入内核&#xff0c;找到 linux-4.9/drivers/net/wireless 文件夹中&#xff0c;新建文件夹aic8800 并且把上面的驱动与文件夹放入刚刚创建好的 aic8800 中。…

【MySQL】 黑马 MySQL进阶 笔记

文章目录 存储引擎MySQL的体系结构存储引擎概念存储引擎特点InnoDBMyISAMMemory 存储引擎选择 索引概述结构B Tree(多路平衡查找树)B TreeHash为什么InnoDB存储引擎选择使用Btree索引结构? 分类思考题 语法SQL性能分析&#xff08;索引相关&#xff09;SQL执行频率慢查询日志p…

3.3-CoroutineScope/CoroutineContext:从挂起函数里获取 CoroutineContext

文章目录 在 CoroutineScope 获取 CoroutineContext 很简单&#xff0c;只需要在使用的地方使用 coroutineContext 属性就能拿到。比如获取运行的线程&#xff1a; val scope CoroutineScope(EmptyCoroutineContext) scope.launch {val dispatcher coroutineContext[Continu…

SSRF和CSRF实战复现

文章目录 SSRFWeb-Hacking-Lab-master1、Centos未授权访问2、Ubuntu未授权访问3、Ubuntu传入公钥访问4、ssrf_redis_lab_pickle_redis_lab CSRF:windphp SSRF SSRF(Server-Side Request Forgery:服务器端请求伪造) 是一种由攻击者构造形成由服务端发起请求的一个安全漏洞。 f…

RAG与LLM原理及实践(14)---- Python + MinIO + Kafka进阶

目录 背景 根因分析 配置 构造 创建 network 构造 zookeeper 构造 kafka 参数构造 原理解析 图解 全过程解析 工具使用 kafkacat 查看 broker python 实现 python send + kafka recv python 代码 kafka recv 运行效果 python recv + kafka send python 代…

Pytest学习总结

文章目录 前言一、pytest单元测试框架1.单元测试框架和自动化测试框架的关系2.pytest简介 二、pytest使用1.使用规则2.运行方式参数详解 3.运行顺序4.分组执行&#xff08;冒烟、分模块执行、分接口和web执行&#xff09;5.pytest跳过测试用例6.使用pytest.fixture()实现部分测…

Unity 波函数坍缩算法随机地图生成

Unity 波函数坍缩算法随机地图生成 波函数波函数基本概念位置空间波函数动量空间波函数两种波函数之间的关系波函数的本征值和本征态波函数坍缩 熵是什么熵作为状态函数时间之箭 实现原理举个例子&#xff1a;2D迷宫地图生成 Unity 如何实现前期准备单元格代码瓦片地图代码波函…

ComfyUI 常用的节点

总的来说&#xff0c;如果可以的话 最佳实践是直接访问每个节点仓库&#xff0c;仔细阅读作者提供的文档和说明。然后&#xff0c;手动执行 git clone 来获取仓库的代码。 接着&#xff0c;你可以通过手动执行 pip install -r requirements.txt 来安装每个项目的依赖。这种方法…