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); } }
「其他文章」
- 執行緒池底層原理詳解與原始碼分析
- 30分鐘掌握 Webpack
- 線性迴歸大結局(嶺(Ridge)、 Lasso迴歸原理、公式推導),你想要的這裡都有
- 【前端必會】webpack loader 到底是什麼
- 中心化決議管理——雲端分析
- HashMap底層原理及jdk1.8原始碼解讀
- 詳解JS中 call 方法的實現
- 列印 Logger 日誌時,需不需要再封裝一下工具類?
- 初識設計模式 - 代理模式
- 密碼學奇妙之旅、01 CFB密文反饋模式、AES標準、Golang程式碼
- Springboot之 Mybatis 多資料來源實現
- CAS核心思想、底層實現
- 面試突擊86:SpringBoot 事務不回滾?怎麼解決?
- 基於electron vue element構建專案模板之【打包篇】
- MiniWord .NET Word模板引擎,藉由Word模板和資料簡單、快速生成檔案。
- 認識執行緒,初始併發
- 1-VSCode搭建GD32開發環境
- 初識設計模式 - 原型模式
- 執行緒安全問題的產生條件、解決方式
- 2>&1到底是什麼意思?