Springboot之 Mybatis 多数据源实现
简介
上篇讲解了 JPA 多数据源实现;这篇讲解一下 Mybatis 多数据源实现 。主要采用将不同数据库的 Mapper 接口分别存放到不同的 package,Spring 去扫描不同的包,注入不同的数据源来实现多数据源。原理跟 JPA 多数据源实现基本一致。
创建 mybatis-multip-datasource 项目
数据库脚本参考:
pom.xml文件引入如下依赖
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.olive</groupId>
<artifactId>mybatis-multip-datasource</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>jpa-multip-datasource</name>
<url>http://maven.apache.org</url>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.14</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.3</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
</project>
配置两个数据源
分别为第一个主数据源(primary),第二数据源(second),具体配置如下:
# 基本配置
server:
port: 8080
# 数据库
spring:
datasource:
primary:
driver-class-name: com.mysql.jdbc.Driver
jdbc-url: jdbc:mysql://127.0.0.1:3306/db01?characterEncoding=utf-8&allowMultiQueries=true&autoReconnect=true
username: root
password: root
second:
driver-class-name: com.mysql.cj.jdbc.Driver
jdbc-url: jdbc:mysql://127.0.0.1:3306/crm72?characterEncoding=utf-8&allowMultiQueries=true&autoReconnect=true
username: root
password: root
jackson:
serialization:
indent-output: true
配置数据源
DataSourceConfig配置
package com.olive.config;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import javax.sql.DataSource;
/**
* @Description: 数据源配置
*/
@Configuration
public class DataSourceConfig {
@Bean(name = "primaryDataSource")
@Qualifier("primaryDataSource")
@ConfigurationProperties(prefix = "spring.datasource.primary")
@Primary
public DataSource primaryDataSource() {
return DataSourceBuilder.create().build();
}
@Bean(name = "secondDataSource")
@Qualifier("secondDataSource")
@ConfigurationProperties(prefix = "spring.datasource.second")
public DataSource secondDataSource() {
return DataSourceBuilder.create().build();
}
}
PrimaryConfig数据源
/**
* @Description: 主数据源配置
*/
@Configuration
@MapperScan(basePackages = "com.olive.mapper.primary",
sqlSessionTemplateRef = "primarySqlSessionTemplate")
public class PrimaryConfig {
@Autowired
@Qualifier("primaryDataSource")
private DataSource primaryDataSource;
@Bean(name = "primarySqlSessionFactory")
@Primary
public SqlSessionFactory primarySqlSessionFacotory() throws Exception {
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(primaryDataSource);
sqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver()
.getResources("classpath:mapper/primary/*.xml"));
return sqlSessionFactoryBean.getObject();
}
@Bean(name = "primaryTransactionManager")
@Primary
public DataSourceTransactionManager primaryTransactionManager() {
return new DataSourceTransactionManager(primaryDataSource);
}
@Bean(name = "primarySqlSessionTemplate")
@Primary
public SqlSessionTemplate primarySqlSessionTemplate(@Qualifier("primarySqlSessionFactory") SqlSessionFactory sqlSessionFactory) {
return new SqlSessionTemplate(sqlSessionFactory);
}
}
SecondConfig数据源
/**
* @Description: 主数据源配置
*/
@Configuration
@MapperScan(basePackages = "com.olive.mapper.second",
sqlSessionTemplateRef = "secondSqlSessionTemplate")
public class SecondConfig {
@Autowired
@Qualifier("secondDataSource")
private DataSource secondDataSource;
@Bean(name = "secondSqlSessionFactory")
public SqlSessionFactory secondSqlSessionFacotory() throws Exception {
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(secondDataSource);
sqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver()
.getResources("classpath:mapper/second/*.xml"));
return sqlSessionFactoryBean.getObject();
}
@Bean(name = "secondTransactionManager")
public DataSourceTransactionManager secondTransactionManager() {
return new DataSourceTransactionManager(secondDataSource);
}
@Bean(name = "secondSqlSessionTemplate")
public SqlSessionTemplate secondSqlSessionTemplate(@Qualifier("secondSqlSessionFactory") SqlSessionFactory sqlSessionFactory) {
return new SqlSessionTemplate(sqlSessionFactory);
}
}
创建学生与老师实体类
Student实体类
package com.olive.entity.primary;
import java.io.Serializable;
import lombok.Data;
@Data
public class StudentDO implements Serializable{
private Long id;
private String name;
private int sex;
private String grade;
}
Teacher实体类
package com.olive.entity.second;
import java.io.Serializable;
import lombok.Data;
@Data
public class TeacherDO implements Serializable {
private Long id;
private String name;
private int sex;
private String office;
}
数据库持久类
StudentMapper类
package com.olive.mapper.primary;
import com.olive.entity.primary.StudentDO;
import org.apache.ibatis.annotations.Param;
public interface StudentMapper {
int save(@Param("studentDO") StudentDO studentDO);
}
TeacherMapper类
package com.olive.mapper.second;
import com.olive.entity.second.TeacherDO;
import org.apache.ibatis.annotations.Param;
public interface TeacherMapper {
int save(@Param("teacherDO") TeacherDO teacherDO);
}
Mybatis xml映射
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.olive.mapper.primary.StudentMapper">
<resultMap id="BaseResultMap" type="com.olive.entity.primary.StudentDO">
<id column="id" jdbcType="BIGINT" property="id" />
<result column="name" jdbcType="VARCHAR" property="name" />
<result column="sex" jdbcType="INTEGER" property="sex" />
<result column="grade" jdbcType="VARCHAR" property="grade" />
</resultMap>
<insert id="save">
INSERT INTO t_student (user_name, sex, grade) VALUES (#{studentDO.name}, #{studentDO.sex}, #{studentDO.grade});
</insert>
</mapper>
TeacherMapper.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.olive.mapper.second.TeacherMapper">
<resultMap id="BaseResultMap" type="com.olive.entity.second.TeacherDO">
<id column="id" jdbcType="BIGINT" property="id" />
<result column="name" jdbcType="VARCHAR" property="name" />
<result column="sex" jdbcType="INTEGER" property="sex" />
<result column="office" jdbcType="VARCHAR" property="office" />
</resultMap>
<insert id="save">
INSERT INTO t_teacher ( user_name, sex, office) VALUES (#{teacherDO.name}, #{teacherDO.sex}, #{teacherDO.office});
</insert>
</mapper>
主要注意这两个xml文件需要放到不同的目录,如下图

创建springboot引导类
package com.olive;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class);
}
}
测试
package com.olive;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import com.olive.entity.primary.StudentDO;
import com.olive.entity.second.TeacherDO;
import com.olive.mapper.primary.StudentMapper;
import com.olive.mapper.second.TeacherMapper;
@SpringBootTest
public class MybatisTest {
@Autowired
StudentMapper studentMapper;
@Autowired
TeacherMapper teacherMapper;
@Test
public void userSave() {
StudentDO studentDO = new StudentDO();
studentDO.setName("BUG弄潮儿");
studentDO.setSex(1);
studentDO.setGrade("一年级");
studentMapper.save(studentDO);
TeacherDO teacherDO = new TeacherDO();
teacherDO.setName("Java乐园");
teacherDO.setSex(2);
teacherDO.setOffice("语文");
teacherMapper.save(teacherDO);
}
}
Springboot之 Mybatis 多数据源实现的更多相关文章
- SpringBoot整合Mybatis多数据源 (AOP+注解)
SpringBoot整合Mybatis多数据源 (AOP+注解) 1.pom.xml文件(开发用的JDK 10) <?xml version="1.0" encoding=& ...
- 三、SpringBoot 整合mybatis 多数据源以及分库分表
前言 说实话,这章本来不打算讲的,因为配置多数据源的网上有很多类似的教程.但是最近因为项目要用到分库分表,所以让我研究一下看怎么实现.我想着上一篇博客讲了多环境的配置,不同的环境调用不同的数据库,那接 ...
- SpringBoot整合Mybatis,多数据源,事务,支持java -jar 启动.
用了一段时间SpringBoot,之前配置MYBATIS ,在打包WAR 放到tomcat下正常,但是WAR已经过时了,现在流行直接打包JAR 丢到DOCKER 里,无奈JAR 启动的时候MAPPER ...
- SpringBoot整合mybatis多数据源,支持分布式事务
编码工具:IDEA SpringBoot版本:2.0.1 JDK版本:1.8 1.使用IDEA构建一个Maven工程 ,添加依赖: <?xml version="1.0" e ...
- springboot:mybatis多数据源配置
1.application.properties #CMS数据源(主库) spring.datasource.cms.driver-class-name=com.mysql.jdbc.Driver s ...
- spring-boot整合Mybatis多数据源案例
1.运行环境 开发工具:intellij idea JDK版本:1.8 项目管理工具:Maven 4.0.0 2.GITHUB地址 https://github.com/nbfujx/springBo ...
- SpringBoot入门之基于Druid配置Mybatis多数据源
上一篇了解了Druid进行配置连接池的监控和慢sql处理,这篇了解下使用基于基于Druid配置Mybatis多数据源.SpringBoot默认配置数据库连接信息时只需设置url等属性信息就可以了,Sp ...
- 第八章 springboot + mybatis + 多数据源(转载)
本篇博客转发自:http://www.cnblogs.com/java-zhao/p/5413845.html 在实际开发中,我们一个项目可能会用到多个数据库,通常一个数据库对应一个数据源. 代码结构 ...
- SpringBoot整合Mybatis之项目结构、数据源
已经有好些日子没有总结了,不是变懒了,而是我一直在奋力学习springboot的路上,现在也算是完成了第一阶段的学习,今天给各位总结总结. 之前在网上找过不少关于springboot的教程,都是一些比 ...
随机推荐
- App Inventor拓展项目——钢琴游戏
本以为安卓只能写代码开发呢,结果安卓课程是这样一个图形化的开发方式,趣味性强一些吧.这里记录一下自己根据学习内容拓展的这个钢琴游戏. 先简要介绍一下 Android应用开发者(英语:App Inven ...
- 9.2 DAG上的动态规划
在有向无环图上的动态规划是学习动态规划的基础,很多问题都可以转化为DAG上的最长路,最短路或路径计数问题 9.2.1 DAG模型 嵌套矩形问题: 矩形之间的可嵌套关系是一种典型的二元关系,二元关系可以 ...
- typescript中的esModuleInterop选项
当没有加esModuleInterop时 库的代码: export const a = 1; export default function b() {} 生成代码 exports.__esModul ...
- 说起分布式自增ID只知道UUID?SnowFlake(雪花)算法了解一下(Python3.0实现)
原文转载自「刘悦的技术博客」https://v3u.cn/a_id_155 但凡说起分布式系统,我们肯定会对一些海量级的业务进行分拆,比如:用户表,订单表.因为数据量巨大一张表完全无法支撑,就会对其进 ...
- Linux系列之重定向操作
前言 I/O重定向允许我们将命令的输入和输出重定向到文件中,以及将多个命令连接到一起成为管道.本文就来介绍有关重定向的知识. 标准输入.输出.错误 输出包括两种类型: 程序的结果.被称为标准输出或者s ...
- .NET 6学习笔记(4)——解决VS2022中Nullable警告
很多小伙伴在升级到Visual Studio 2022后发现,如果我们去新建一个.NET 6的项目,和原先VS2019中一摸一样的写法,却会出现CS8618 Non-nullable property ...
- Uniapp---快速生成安卓证书keystore文件
在用Uniapp开发项目的时候,APP上线,就需要用到安卓证书,当然网上有很多生成证书的教程,各种安装,各种命令,下面就介绍两种快速方便的生成证书的方法: 第一种:在线证书生成: http://www ...
- 多线程与高并发(五)—— 源码解析 ReentrantLock
一.前言 ReentrantLock 是基于 AQS 实现的同步框架,关于 AQS 的源码在 这篇文章 已经讲解过,ReentrantLock 的主要实现都依赖AQS,因此在阅读本文前应该先了解 AQ ...
- 如何实现 System.out.println("a") 显示 b
今天看到一篇文章不用反射,能否交换两个字符串的值. 心想字符串常量在常量池里面,是在就算用了反射也交换不了吧.转念一想,不对,字符串常量虽然本身在常量池里面,但是它依然是个对象,那么 private ...
- iOS白嫖系列Testflight
1.Picsart 白嫖一年会员 使用 Picsart 照片编辑器和视频编辑器,您可以将您的创意变为现实.制作专业级拼贴画.设计和添加贴纸.快速移除和交换背景.尝试热门编辑,如黄金时段.镜子自拍和复古 ...