SpringBoot+Mybatis实现多数据源+分页

1 主要依赖版本

(1)SpringBoot 2.7.8

(2)Mybatis 2.2.2

(3)Pagehelper 1.3.0

(4)MySQL 8.0.26

(5)Oracle 11.2.0.3

2 概述

(1)这里使用两个数据源,分别是MySQL和Oracle,配置两个数据库;

(2)针对以上数据源分别配置Mybatis和Pagehelper(实现分页);

(3)数据源、Mybatis、分页都自定义配置,在启动类关闭它们的自动配置。

3 SpringBoot整合Mybatis实现多数据源动态切换

3.1 整合与配置

3.1.1 相关依赖pom.xml

<!-- mybatis-spring-boot-starter -->
<dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>2.2.2</version>
</dependency>
<!-- pagehelper-spring-boot-starter -->
<dependency><groupId>com.github.pagehelper</groupId><artifactId>pagehelper-spring-boot-starter</artifactId><version>1.3.0</version>
</dependency>
<!-- mysql -->
<dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.26</version><scope>runtime</scope>
</dependency>
<!-- oracle -->
<dependency><groupId>com.oracle</groupId><artifactId>ojdbc6</artifactId><version>11.2.0.3</version>
</dependency>
<!-- hutool -->
<dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.7.22</version>
</dependency>
<!-- yml文件自定义配置,输入提示-->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-configuration-processor</artifactId><optional>true</optional>
</dependency>

3.1.2 application.yml配置

        yml配置中配置了db1和db2两个数据源以及分页,db1对应MySQL,db2对应Oracle,如果不需要分页这里可以省去spring.pagehelper下的配置。

spring:datasource:db1:driver-class-name: com.mysql.cj.jdbc.Driverjdbc-url: jdbc:mysql://localhost:3306/studb?characterEncoding=UTF-8&useUnicode=trueusername: rootpassword: rootdb2:driver-class-name: oracle.jdbc.driver.OracleDriverjdbc-url: jdbc:oracle:thin:@//localhost:1521/XEusername: rootpassword: root
#  分页配置pagehelper:db1:dialect: mysqloffsetAsPageNum: truerowBoundsWithCount: truereasonable: truesupportMethodsArguments: trueparams: count=countSql;pageNum=pageNum;pageSize=pageSize;db2:dialect: oracleoffsetAsPageNum: truerowBoundsWithCount: truereasonable: truesupportMethodsArguments: trueparams: count=countSql;pageNum=pageNum;pageSize=pageSize;

3.1.3 yml中分页配置设置到对应Bean

        这里使用@ConfigurationProperties注解将yml配置文件中指定前缀的数据自动填充到Bean。

(1)db1数据源的分页属性Bean

@Data
@Component
@ConfigurationProperties(prefix = "spring.pagehelper.db1")
public class PrimaryMybatisProperties {private String dialect;private String offsetAsPageNum;private String rowBoundsWithCount;private String reasonable;private String supportMethodsArguments;private String params;
}

(2)db2数据源的分页属性Bean

@Data
@Component
@ConfigurationProperties(prefix = "spring.pagehelper.db2")
public class SecondMybatisProperties {private String dialect;private String offsetAsPageNum;private String rowBoundsWithCount;private String reasonable;private String supportMethodsArguments;private String params;
}

3.1.4 数据源配置

(1)db1的数据源配置PrimaryDataSourceConfig.java

注意:多数据源情况下这里使用@Primary注解指定默认使用的是db1。

@Configuration
@MapperScan(basePackages = "com.wen.mapper1", sqlSessionFactoryRef = "sqlSessionFactory1")
public class PrimaryDataSourceConfig {@Resourceprivate PrimaryMybatisProperties primaryMybatisProperties;@Bean(name = "dataSource1")@Primary@ConfigurationProperties(prefix = "spring.datasource.db1")public DataSource dataSource1(){return DataSourceBuilder.create().build();}@Bean(name = "sqlSessionFactory1")@Primarypublic SqlSessionFactory sqlSessionFactory1(@Qualifier("dataSource1") DataSource dataSource1) throws Exception{SqlSessionFactoryBean sessionFactoryBean = new SqlSessionFactoryBean();sessionFactoryBean.setDataSource(dataSource1);String locationPattern = "classpath*:mapper1/**/*.xml";PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();sessionFactoryBean.setMapperLocations(resolver.getResources(locationPattern));// mybatisorg.apache.ibatis.session.Configuration configuration = new org.apache.ibatis.session.Configuration();configuration.setMapUnderscoreToCamelCase(true);configuration.setLogImpl(StdOutImpl.class);sessionFactoryBean.setConfiguration(configuration);// 分页Interceptor interceptor = new PageInterceptor();Properties properties = new Properties();properties.setProperty("helperDialect", primaryMybatisProperties.getDialect());properties.setProperty("offsetAsPageNum", primaryMybatisProperties.getOffsetAsPageNum());properties.setProperty("rowBoundsWithCount", primaryMybatisProperties.getRowBoundsWithCount());properties.setProperty("reasonable", primaryMybatisProperties.getReasonable());properties.setProperty("supportMethodsArguments",primaryMybatisProperties.getSupportMethodsArguments());properties.setProperty("params",primaryMybatisProperties.getParams());interceptor.setProperties(properties);sessionFactoryBean.setPlugins(interceptor);return sessionFactoryBean.getObject();}@Bean(name = "sqlSessionTemplate1")@Primarypublic SqlSessionTemplate sqlSessionTemplate1(@Qualifier("sqlSessionFactory1") SqlSessionFactory sqlSessionFactory1) {return new SqlSessionTemplate(sqlSessionFactory1);}@Bean(name = "dataSourceTransactionManager1")@Primarypublic DataSourceTransactionManager dataSourceTransactionManager1(@Qualifier("dataSource1") DataSource dataSource1){return new DataSourceTransactionManager(dataSource1);}
}

(2)db2的数据源配置SecondDataSourceConfig.java

@Configuration
@MapperScan(basePackages = "com.wen.mapper2",sqlSessionFactoryRef = "sqlSessionFactory2")
public class SecondDataSourceConfig {@Resourceprivate SecondMybatisProperties secondMybatisProperties;@Bean(name = "dataSource2")@Primary@ConfigurationProperties(prefix = "spring.datasource.db2")public DataSource dataSource2(){return DataSourceBuilder.create().build();}@Bean(name = "sqlSessionFactory2")@Primarypublic SqlSessionFactory sqlSessionFactory1(@Qualifier("dataSource2") DataSource dataSource2) throws Exception{SqlSessionFactoryBean sessionFactoryBean = new SqlSessionFactoryBean();sessionFactoryBean.setDataSource(dataSource2);String locationPattern = "classpath*:mapper2/**/*.xml";PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();sessionFactoryBean.setMapperLocations(resolver.getResources(locationPattern));// mybatis下划线转驼峰org.apache.ibatis.session.Configuration configuration = new org.apache.ibatis.session.Configuration();configuration.setMapUnderscoreToCamelCase(true);configuration.setLogImpl(StdOutImpl.class);sessionFactoryBean.setConfiguration(configuration);// 分页配置Interceptor interceptor = new PageInterceptor();Properties properties = new Properties();properties.setProperty("helperDialect", secondMybatisProperties.getDialect());properties.setProperty("offsetAsPageNum", secondMybatisProperties.getOffsetAsPageNum());properties.setProperty("rowBoundsWithCount", secondMybatisProperties.getRowBoundsWithCount());properties.setProperty("reasonable", secondMybatisProperties.getReasonable());properties.setProperty("supportMethodsArguments",secondMybatisProperties.getSupportMethodsArguments());properties.setProperty("params",secondMybatisProperties.getParams());interceptor.setProperties(properties);sessionFactoryBean.setPlugins(interceptor);return sessionFactoryBean.getObject();}@Bean(name = "sqlSessionTemplate2")@Primarypublic SqlSessionTemplate sqlSessionTemplate1(@Qualifier("sqlSessionFactory2") SqlSessionFactory sqlSessionFactory2) {return new SqlSessionTemplate(sqlSessionFactory2);}@Bean(name = "dataSourceTransactionManager2")@Primarypublic DataSourceTransactionManager dataSourceTransactionManager1(@Qualifier("dataSource2") DataSource dataSource2){return new DataSourceTransactionManager(dataSource2);}
}

注意:如果项目中有使用@Transactional事务注解,必须分别配置数据源的事务管理,以上代码中已经配置。

3.1.5 启动类排除相关自动配置

        启动类排除数据源(DataSourceAutoConfiguration.class)、Mybatis(MybatisAutoConfiguration.class)、分页(PageHelperAutoConfiguration.class)的自动配置。

@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class, MybatisAutoConfiguration.class, PageHelperAutoConfiguration.class})
public class Application {public static void main(String[] args) {SpringApplication.run(Application.class, args);}}

3.2 示例代码

3.2.1 po

src/main/java/com/wen/po

@Data
public class Student {private Integer id;private String name;private Integer age;private String gender;private String address;private Date birth;
}
@Data
public class User {private String id;private String userName;
}

3.2.2 controller层

src/main/java/com/wen/controller

@RestController
@RequestMapping("/student")
public class StudentController {@Resourceprivate StudentServiceI studentService;@GetMappingpublic PageInfo<Student> queryByPage(int pageNum, int pageSize, Student student){return studentService.queryByPage(pageNum,pageSize,student);}
}
@RestController
@RequestMapping("/user")
public class UserController {@Resourceprivate UserServiceI userService;@GetMappingpublic PageInfo<User> queryByPage(int pageNum, int pageSize, User user){return userService.queryByPage(pageNum,pageSize,user);}
}

3.2.3 service层

src/main/java/com/wen/service

public interface StudentServiceI {PageInfo<Student> queryByPage(int pageNum, int pageSize, Student student);}
@Service
public class StudentServiceImpl implements StudentServiceI {@Resourceprivate StudentMapper studentMapper;@Overridepublic PageInfo<Student> queryByPage(int pageNum, int pageSize, Student student) {if (pageNum <= 0) {pageNum = 1;}if (pageSize <= 0) {pageSize = 10;}if(ObjectUtil.isEmpty(student)){student = new Student();}PageMethod.startPage(pageNum,pageSize);List<Student> students = studentMapper.selectByPage(student);PageInfo<Student> pageInfo = new PageInfo<>(students);return pageInfo;}
}
public interface UserServiceI {PageInfo<User> queryByPage(int pageNum, int pageSize, User user);
}
@Service
public class UserServiceImpl implements UserServiceI {@Resourceprivate UserMapper userMapper;@Overridepublic PageInfo<User> queryByPage(int pageNum, int pageSize, User user) {if (pageNum <= 0) {pageNum = 1;}if (pageSize <= 0) {pageSize = 10;}if(ObjectUtil.isEmpty(user)){user = new User();}PageMethod.startPage(pageNum,pageSize);List<User> users = userMapper.selectByPage(user);PageInfo<User> pageInfo = new PageInfo<>(users);return pageInfo;}
}

3.2.4 mapper层

        注意不同数据源对应的mapper,数据源配置类中@MapperScan对应的属性basePackages = "com.wen.mapper2"指定数据源对应的mapper。

(1)db1数据源对应的mapper层

src/main/java/com/wen/mapper1/StudentMapper.java

@Mapper
public interface StudentMapper {List<Student> selectByPage(@Param("student") Student student);
}

src/main/resources/mapper1/StudentMapper.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.wen.mapper1.StudentMapper"><sql id="student">id,name,age,gender,address,birth</sql><select id="selectByPage" resultType="com.wen.po.Student">select<include refid="student"/>from student<where><if test="student.id!=null">and id = #{student.id}</if><if test="student.name!=null and student.name!=''"><bind name="stuName" value="'%' + student.name + '%'"/>and name like #{stuName}</if></where></select>
</mapper>

(2)db2数据源对应的mapper层

src/main/java/com/wen/mapper2/UserMapper.java

@Mapper
public interface UserMapper {List<User> selectByPage(@Param("user") User user);
}

src/main/resources/mapper2/UserMapper.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.wen.mapper2.UserMapper"><sql id="user">id,user_name</sql><select id="selectByPage" resultType="com.wen.po.User">select<include refid="user"/>from sys_user<where><if test="user.id!=null">and id = #{student.id}</if><if test="user.userName!=null and user.userName!=''"><bind name="userName" value="'%' + user.userName + '%'"/>and user_name like #{userName}</if></where></select>
</mapper>

3.3 测试

        使用Postman进行测试,如下:

(1)使用db1数据源

(2)使用db2数据源

 

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

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

相关文章

List集合拆分为多个List

list 拆分 目录概述需求&#xff1a; 设计思路实现思路分析1.list 拆分是2.用stream的parallel实现list的分批处理3.使用stream的parallel实现list的分批处理 参考资料和推荐阅读 Survive by day and develop by night. talk for import biz , show your perfect code,full bus…

[架构之路-239]:目标系统 - 纵向分层 - 中间件middleware

目录 前言&#xff1a; 一、中间件概述 1.1 中间件在软件层次中的位置 1.2 什么是中间件 1.3 为什么需要中间件 1.4 中间件应用场合&#xff08;应用程序不用的底层需求&#xff1a;计算、存储、通信&#xff09; 1.5 中间件分类 - 按内容分 二、嵌入式系统的中间件 2…

uniapp(uncloud) 使用生态开发接口详情4(wangeditor 富文本, 云对象, postman 网络请求)

wangeditor 官网: https://www.wangeditor.com/v4/pages/01-%E5%BC%80%E5%A7%8B%E4%BD%BF%E7%94%A8/01-%E5%9F%BA%E6%9C%AC%E4%BD%BF%E7%94%A8.html 这里用vue2版本,用wangeditor 4 终端命令: npm i wangeditor --save 开始使用 在项目pages > sy_news > add.vue 页面中…

Docker部署Jumpserver堡垒机

Jumpserver 是全球首款完全开源的堡垒机&#xff0c;使用 GNU GPL v2.0 开源协议&#xff0c;是符合 4A 的专业运维审计系统。 Jumpserver 使用 Python / Django 进行开发&#xff0c;遵循 Web 2.0 规范&#xff0c;配备了业界领先的 Web Terminal 解决方案&#xff0c;交互界面…

优雅而高效的JavaScript——?? 运算符、?. 运算符和 ?. .运算符

&#x1f974;博主&#xff1a;小猫娃来啦 &#x1f974;文章核心&#xff1a;优雅而高效的JavaScript——?? 运算符、?. 运算符和 ?. 运算符 文章目录 引言空值处理的挑战解决方案1&#xff1a;?? 运算符基本用法与 || 运算符的区别实际应用场景举例 解决方案2&#xff…

jenkins出错与恢复

如果你的jenkins出现了如下图所示问题&#xff08;比如不能下载插件&#xff0c;无法保存任务等&#xff09;&#xff0c;这个时候就需要重新安装了。 一、卸载干净jenknis 要彻底卸载 Jenkins&#xff0c;您可以按照以下步骤进行操作&#xff1a; 1、停止 Jenkins 服务&…

CCC数字钥匙设计【NFC】--通过NFC进行车主配对Phase3

1、车主配对流程介绍 车主配对可以通过车内NFC进行&#xff0c;若支持UWB测距&#xff0c;也可以通过蓝牙/UWB进行。通过NFC进行车主配对总共有5个Phase。本文档主要对Phase3进行介绍。 1) Phase0&#xff1a;准备阶段&#xff1b; 2) Phase1&#xff1a;启动流程&#xff1…

攻防世界web篇-unserialize3

得出php代码残篇 将代码补全后再在线php运行工具中进行运行 在浏览器输入后得到下面的界面 这里需要将O:4:“xctf”:1:{s:4:“flag”;s:3:“111”;} 改为 O:4:“xctf”:2:{s:4:“flag”;s:3:“111”;}

从零实现FFmpeg6.0+ SDL2播放器

FFmpeg6.0开发环境搭建播放器代码框架分析解复用模块开发实现包队列和帧队列设计音视频解码线程实现SDL2音频声音输出SDL2视频画面渲染-YUV显示音视频同步-基于音频 地址: https://xxetb.xet.tech/s/3NWJGf

【STM32】--基础了解

一、STM32来历背景 1.从51到STM32 &#xff08;1&#xff09;单片机有很多种 &#xff08;2&#xff09;STM32内核使用ARM&#xff0c;但是ARM不一定是STM32 &#xff08;3&#xff09;ATM32是当前主流的32位高性能单片机 &#xff08;4&#xff09;STM32的特点&#xff1a;高…

docker入门加实战—部署Java和前端项目

docker入门加实战—部署Java和前端项目 部署之前&#xff0c;先删除nginx&#xff0c;和自己创建的dd两个容器&#xff1a; docker rm -f nginx dd部署Java项目 作为演示&#xff0c;我们的Java项目比较简单&#xff0c;提供了一个接口&#xff1a; 配置文件连接docker里的m…

03、爬取资料---但是失败,仅作为记录

1、找网址 进入直播间&#xff0c;里面的用户被设置不对外查看。 如图&#xff0c;找url 2、伪装 user-agent 用户代理 cookie 用户登录后保留的信息 登录信息&#xff1a;找cookie 浏览器信息&#xff1a;找user-agent user-agent 用户代理 cookie 用户登录后保留的信…

Linux-Jconsole连接远程服务器

Jconsole连接远程服务器 一、修改jmxremote.password.template文件二、启动jar项目三、jconsole远程连接1、打开的你jconsole2、远程连接 一、修改jmxremote.password.template文件 进去你的/idk/jre/lib/management目录下可以看到jmxremote.password.template文件 修改jmxr…

sqoop 脚本密码管理

1&#xff1a;背景 生产上很多sqoop脚本的密码都是铭文&#xff0c;很不安全&#xff0c;找了一些帖子&#xff0c;自己尝试了下&#xff0c;记录下细节&#xff0c;使用的方式是将密码存在hdfs上然后在脚本里用别名来替代。 2&#xff1a;正文 第一步&#xff1a;创建密码对…

中文编程开发语言工具编程实际案例:美发店会员管理系统软件编程实例

中文编程开发语言工具编程实际案例&#xff1a;美发店会员管理系统软件编程实例 中文编程开发语言工具编程实际案例&#xff1a;美发店会员管理系统软件编程实例。 软件功能&#xff1a; 1、系统设置&#xff1a;参数设定&#xff0c;账号及权限设置&#xff0c;系统初始化&a…

minikube创建一个pod并暴露端口(使用docker驱动安装)

因为minikube使用service暴露端口是使用nodeIP:nodePort 而不是 localhost:nodePort 公开访问。我们只能使用kubectl的端口转发功能或者使用iptables的转发功能来实现外网服务暴露。 我这里使用shiro来举例 apiVersion: apps/v1 kind: Deployment metadata:name: shiro550 spe…

人工智能(pytorch)搭建模型20-基于pytorch搭建文本生成视频的生成对抗网络,技术创新点介绍

大家好&#xff0c;我是微学AI&#xff0c;今天给大家介绍一下人工智能(pytorch)搭建模型20-基于pytorch搭建文本生成视频的生成对抗网络&#xff0c;技术创新点介绍&#xff0c;随着人工智能和深度学习技术的飞速发展&#xff0c;文本到视频生成已经成为计算机视觉领域中一个重…

语法分析出错,不是 GROUP BY 表达式

报错 ### Cause: dm.jdbc.driver.DMException: 第 9 行, 第 69 列[30]附近出现错误: 语法分析出错 ; bad SQL grammar []; nested exception is dm.jdbc.driver.DMException: 第 9 行, 第 69 列[30]附近出现错误: 语法分析出错at org.springframework.jdbc.support.SQLState…

【Godot引擎开发】简单基础,外加一个小游戏DEMO

博主&#xff1a;_LJaXi 专栏&#xff1a; Godot | 横版游戏开发 Godot 物体规律移动内置虚函数浮点计算浮点数计算数组APIInput单例与自定义单例节点NodeSprite2DArea2DCollisionShape2DKinematicBody2DRigidBody2D Pong游戏场景安排玩家1玩家2小球记分系统文件概要 下面是介绍…

【C++】C++学习(模板+排序+测时)

本文主要记录使用模板函数来编写排序算法&#xff0c;并计算运行时间。 模板函数&#xff08;Template Function&#xff09;是一种通用函数&#xff0c;可以在其定义时不指定具体的参数类型&#xff0c;在调用时再根据需要指定具体类型。模板函数可以接受不同类型的参数&…