最简单的SpringBoot+MyBatis多数据源实现

news2024/9/20 20:39:50

最简单的SpringBoot+MyBatis多数据源实现

    • 1.数据库准备
    • 2.环境准备
    • 3.代码部分
      • 3.1多数据源配置
      • 2.测试

image-20200708160944615

随着应用用户数量的增加,相应的并发请求的数量也会跟着不断增加,慢慢地,单个数据库已经没有办法满足频繁的数据库操作请求了,在某些场景下,可能会需要配置多个数据源,使用多个数据源(例如实现数据库的读写分离)来缓解系统的压力等,同样的,Springboot官方提供了相应的实现来帮助开发者们配置多数据源,一般分为两种方式(目前所了解到的),分包和AOP。

考虑到mybatis是java开发使用较为频繁的数据库框架,所以使用Springboot+Mybatis来实现多数据源的配置。

1.数据库准备

既然是配置多数据源,那么自然就要先把相应的数据源给准备好,本地新建了两个数据库,如下表:

数据库数据表字段
testdatasource1sys_useruser_id(int), user_name(varchar) user_age(int)
testdatasource2sys_user2同上

并分别插入两条记录,为了方便对比,其中testdatasource1为芳年25岁的张三, testdatasource2为芳年30岁的李四。

2.环境准备

首先新建一个Springboot项目,这里版本是2.1.7.RELEASE,并在pom文件中引入相关依赖:关键依赖如下:

<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>1.3.2</version>
</dependency>

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
</dependency>

3.代码部分

3.1多数据源配置

首先呢,在Springboot的配置文件中配置的datasourse,和以往不一样的是,因为有两个数据源,所以要指定相关数据库的名称,其中主数据源为primary,次数据源为secondary如下:

#配置主数据库
spring.datasource.primary.jdbc-url=jdbc:mysql://localhost:3306/testdatasource1?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC&useSSL=false
spring.datasource.primary.username=root
spring.datasource.primary.password=root
spring.datasource.primary.driver-class-name=com.mysql.cj.jdbc.Driver

##配置次数据库
spring.datasource.secondary.jdbc-url=jdbc:mysql://localhost:3306/testdatasource2?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC&useSSL=false
spring.datasource.secondary.username=root
spring.datasource.secondary.password=root
spring.datasource.secondary.driver-class-name=com.mysql.cj.jdbc.Driver


spring.http.encoding.charset=UTF-8
spring.http.encoding.enabled=true
spring.http.encoding.force=true

需要注意的是,Springboot2.0 在配置数据库连接的时候需要使用jdbc-url,如果只使用url的话会报
jdbcUrl is required with driverClassName.错误。

新建一个配置类PrimaryDataSourceConfig,用于配置的主数据库相关的bean,代码如下:

@Configuration
//basePackages:接口文件的包路径
@MapperScan(basePackages = "com.jdkcb.mybatisstuday.mapper.one", sqlSessionFactoryRef = "PrimarySqlSessionFactory")
public class PrimaryDataSourceConfig {

    @Bean(name = "PrimaryDataSource")
    // 表示这个数据源是默认数据源
    @Primary//这个一定要加,如果两个数据源都没有@Primary会报错
    @ConfigurationProperties(prefix = "spring.datasource.primary")//配置文件中的前缀
    public DataSource getPrimaryDateSource() {
        return DataSourceBuilder.create().build();
    }

    @Bean(name = "PrimarySqlSessionFactory")
    @Primary
    public SqlSessionFactory primarySqlSessionFactory(@Qualifier("PrimaryDataSource") DataSource datasource)
            throws Exception {
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        bean.setDataSource(datasource);
        bean.setMapperLocations( 
                new PathMatchingResourcePatternResolver().getResources("classpath*:mapping/one/*.xml"));
        return bean.getObject();// 设置mybatis的xml所在位置
    }

    @Bean("PrimarySqlSessionTemplate")
    // 表示这个数据源是默认数据源
    @Primary
    public SqlSessionTemplate primarySqlSessionTemplate(
            @Qualifier("PrimarySqlSessionFactory") SqlSessionFactory sessionfactory) {
        return new SqlSessionTemplate(sessionfactory);
    }

}

注解说明:

@MapperScan :配置mybatis的接口类放的地方

@Primary :表示使用的是默认数据库,这个一个要加,否则会因为不知道哪个数据库是默认数据库而报错

@ConfigurationProperties:读取application.properties中的配置参数映射成为一个对象,其中prefix表示参数的前缀

大功告成~ ~ 了吗?并没有,然后配置的第二个数据源的配置类,代码如下:

@Configuration
@MapperScan(basePackages = "com.jdkcb.mybatisstuday.mapper.two", sqlSessionFactoryRef = "SecondarySqlSessionFactory")
public class SecondaryDataSourceConfig {

    @Bean(name = "SecondaryDataSource")
    @ConfigurationProperties(prefix = "spring.datasource.secondary")
    public DataSource getSecondaryDataSource() {
        return DataSourceBuilder.create().build();
    }
    @Bean(name = "SecondarySqlSessionFactory")
    public SqlSessionFactory secondarySqlSessionFactory(@Qualifier("SecondaryDataSource") DataSource datasource)
            throws Exception {
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        bean.setDataSource(datasource);
        bean.setMapperLocations(
                new PathMatchingResourcePatternResolver().getResources("classpath*:mapping/two/*.xml"));
        return bean.getObject();// 设置mybatis的xml所在位置
    }
    @Bean("SecondarySqlSessionTemplate")
    public SqlSessionTemplate secondarySqlSessionTemplate(
            @Qualifier("SecondarySqlSessionFactory") SqlSessionFactory sessionfactory) {
        return new SqlSessionTemplate(sessionfactory);
    }

剩下的就是编写相应的xml文件和接口类了,代码如下:

@Component
@Mapper
public interface PrimaryUserMapper {
    List<User> findAll();
}
@Component
@Mapper
public interface SecondaryUserMapper {
    List<User> findAll();
}

相关的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.jdkcb.mybatisstuday.mapper.one.PrimaryUserMapper">
    <select id="findAll" resultType="com.jdkcb.mybatisstuday.pojo.User">
                select * from sys_user;
    </select>
</mapper>


<?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.jdkcb.mybatisstuday.mapper.two.SecondaryUserMapper">
    <select id="findAll" resultType="com.jdkcb.mybatisstuday.pojo.User">
                select * from sys_user2;
    </select>

</mapper>

注:其中xml文件在本实例中目录为:resources/mapping

2.测试

编写一个Controller用于测试,因为是测试实例且代码相对来说较为简单,所以这里就不写Service层了。

代码如下:

@RestController
public class UserController {

    @Autowired
    private PrimaryUserMapper primaryUserMapper;
    @Autowired
    private SecondaryUserMapper secondaryUserMapper;
    @RequestMapping("/primary")
    public Object primary(){
        List<User> list = primaryUserMapper.findAll();
        return list;
    }
    
    @RequestMapping("/secondary")
    public Object secondary  (){
        List<User> list = secondaryUserMapper.findAll();
        return list;
    }


}

在浏览器分别输入:http://127.0.0.1:8080/primary 和 http://127.0.0.1:8080/secondary

结果如下:

[{"user_id":1,"user_name":"张三","user_age":25}] //primary 
[{"user_id":1,"user_name":"李四","user_age":30}] //secondary

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

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

相关文章

【JeecgBoot-Vue3】第4节 目录结构与常用组件介绍

一、项目的目录结构讲解 1. src/api/ 存放API相关信息 src/api/存放的是调用后台api接口相关信息src/api/commonapi.tsapi接口信息2. src/assets 静态资源 src/assets静态资源 src/assets/icons 图标 src/assets/images 图片 src/assets/less 样式src/assets/svgsvg图像3. s…

函数编程:强大的 Stream API

函数编程&#xff1a;强大的 Stream API 每博一文案 只要有人的地方&#xff0c;世界就不会是冰冷的&#xff0c;我们可以平凡&#xff0c;但绝对不可以平庸。—————— 《平凡的世界》人活着&#xff0c;就得随时准备经受磨难。他已经看过一些书&#xff0c;知道不论是普通…

Python API教程:API入门

什么是API&#xff1f; 一个API&#xff0c;或被称为应用程序接口&#xff0c;是一个服务器为你提供一个接收或发送数据的代码。API通常用来接收数据。 本文就集中焦点在此话题中。 当我们想从一个API中接收数据&#xff0c;我们需要开始请求。请求可以包含整个Web。例如&am…

Vue基础18之github案例、vue-resource

Vue基础18github案例静态页面第三方样式引入&#xff08;以bootstrap举例&#xff09;App.vueSearch.vueList.vue列表展示接口地址使用全局事件总线进行兄弟间组件通信Search.vueList.vue完善案例List.vueSearch.vue补充知识点&#xff1a;{...this.info,...this.dataObj}效果呈…

Serverless

Serverless&#xff1a;云计算的下一个十年 最近几年的技术圈&#xff0c;对于 Serverless 技术的讨论异常火热&#xff0c;在业内也有了很多成熟的案例&#xff0c;国外发展较早&#xff0c;比较有代表性的就是亚马逊和谷歌&#xff0c; 而在国内&#xff0c;腾讯和阿里两位巨…

Maven使用教程

1.什么是Maven&#xff1f; 当我们在创建一个使用Spring的Web项目就需要引入大量的jar包。一个项目Jar包的数量极多&#xff0c;并且Jar包之间的关系错综复杂&#xff0c;一个Jar包往往又会引用其他Jar包&#xff0c;缺少任何一个Jar包都会导致项目编译失败。 以往开发项目时…

GraphPad Prism v9.5.1.733 科研绘图软件多语言

GraphPad Prism集生物统计、曲线拟合和科技绘图于一体,其所具有的功能均非常实用和精炼,包括了一些特色的功能,如ROC曲线分析、Bland-Altman分析等;曲线拟合功能是GraphPad Prism8 汉化版超越其他统计软体的制胜法宝,GraphPad Prism8 汉化版的线性/非线性拟合功能使用操作…

JVM运行时数据区—Java虚拟机栈

虚拟机栈的背景 由于跨平台性的设计&#xff0c;java的指令都是根据栈来设计的。不同平台CPU架构不同&#xff0c;所以不能设计为基于寄存器的。 根据栈设计的优点是跨平台&#xff0c;指令集小&#xff0c;编译器容易实现&#xff0c;缺点是性能下降&#xff0c;实现同样的功…

python制作【法律条文查询工具】妈妈再也不担心我法盲了

前言 嗨喽~大家好呀&#xff0c;这里是魔王呐 ❤ ~! 更多教程源码资料电子书: 点击此处跳转文末名片获取 环境准备8 Python 3.8 Pycharm 《中华人民共和国刑法》 效果展示 打算做个简单的界面&#xff0c;主要功能就是查询法律条文 代码展示 查询器界面 设定界面大小 …

戴眼镜检测和识别2:Pytorch实现戴眼镜检测和识别(含戴眼镜数据集和训练代码)

Pytorch实现戴眼镜检测和识别(含戴眼镜数据集和训练代码) 目录 Pytorch实现戴眼镜检测和识别(含戴眼镜数据集和训练代码) 1.戴眼镜检测和识别方法 2.戴眼镜数据集 3.人脸检测模型 4.戴眼镜分类模型训练 &#xff08;1&#xff09;项目安装 &#xff08;2&#xff09;准…

反向代理和负载均衡有何区别?

反向代理和负载均衡是两种常用的网络架构模式&#xff0c;它们可以一起使用来提高网站的性能和可靠性&#xff0c;很多人会把这两者混淆&#xff0c;实际上&#xff0c;这两者的作用略有不同&#xff0c;今天我们就来详细说说具体区别是什么。一、反向代理&#xff08;Reverse …

Python|贪心|数组|桶排序|二叉搜索树|贪心|单选记录:最大间距|将有序数组转换为二叉搜索树|跳跃游戏 II

1、最大间距&#xff08;数组&#xff0c;桶排序&#xff09; 给定一个无序的数组&#xff0c;找出数组在排序之后&#xff0c;相邻元素之间最大的差值。 如果数组元素个数小于 2&#xff0c;则返回 0。 示例 1: 输入: [3,6,9,1] 输出: 3 解释: 排序后的数组是 [1,3,6,9]…

三个案例场景带你掌握Cisco交换机VLAN互通

VLAN间路由的方式现在主流的组网主要是依靠三层交换机通过配置SVI接口【有的厂商叫VLANIF接口】&#xff0c;当然也有比较小型的网络&#xff0c;它就一个出口路由器可管理的二层交换机&#xff0c;还有一种更加差的&#xff0c;就是出口路由一个可管理的二层交换机&#xff0c…

描述一下锁的四种状态及升级过程?

文章目录1、锁的四种状态2、Java对象头描述3、锁的升级过程&#xff08;Synchronized加锁/膨胀流程&#xff09;1&#xff09;简单过程如下图2&#xff09;详细过程&#xff08;1&#xff09;偏向锁&#xff08;2&#xff09;轻量级锁&#xff08;3&#xff09;重量级锁4、拓展…

SpringBoot下的Spring框架学习(Tedu)——DAY02

SpringBoot下的Spring框架学习&#xff08;Tedu&#xff09;——DAY02 目录SpringBoot下的Spring框架学习&#xff08;Tedu&#xff09;——DAY02Spring框架学习1.1 Spring介绍1.2 知识铺垫1.2.1 编辑Dog类1.2.2 编辑Cat类1.2.3 编辑测试类User.java1.2.4 上述代码的总结1.3 面…

PPQ库中KLD算法实现代码解析

PPQ量化工具库KLD算法解析前言PPQ算法实现NVIDIA的PPT中KLD算法流程KLD算法PPQ实现版本PPQ与NVIDIA的区别&#xff1a;前言 这是对PPQ库中KLD算法实现代码解析&#xff0c;关于PPQ库安装与使用详情见专栏上一篇博客。 PPQ算法实现 nvidia发布的PPT&#xff1a;8-bit Inferen…

使用vue-element-admin进行二次开发

vue-element-admin 介绍 基于 vue 和 element-ui实现 的后台前端解决方案 集成方案: vue-element-admin基础模板: vue-admin-template桌面终端: electron-vue-adminTypescript 版: vue-typescript-admin-template Others: awesome-project 亮点 i18 国际化解决方案 动态路由…

射频功率放大器在辉光放电特征及风速测量原理中的应用

实验名称&#xff1a;辉光放电特征及风速测量原理研究方向&#xff1a;辉光放电测试设备&#xff1a;信号发生器、ATA-8202射频功率放大器&#xff0c;热成像仪、万用表、等离子体传感器实验过程&#xff1a;在等离子体形成条件和流场响应机制的基础上&#xff0c;可以明确影响…

node使用支付宝沙箱模拟支付-好文

首页打开支付宝官方进行登录&#xff1a;支付宝开放平台 (alipay.com)下载支付宝提供的秘钥转化工具&#xff1a;密钥工具下载 - 支付宝文档中心 (alipay.com)打开工具生成密码&#xff1a;然后在支付宝页面配置秘钥开始配置nodenpm init -y初始化&#xff0c;再npm i express跟…

<Linux>进程间通信--管道

前言&#x1f603;&#x1f603;&#x1f603;进程间通信的方式管道 - Linux原生提供2SystemV - 多线程单机通信posix - 多线程网络通信这里我们主要是介绍一下管道一、生活和计算机中的管道&#x1f61c;生活中的管道特点都是有出口和入口的都是单向传输内容的(例如&#xff1…