前言

MyBatis 多数据源配置,最近在项目建设中,需要在原有系统上扩展一个新的业务模块,特意将数据库分库,以便减少复杂度。本文直接以简单的代码示例,如何对 MyBatis 多数据源配置。

准备

创建数据库

db_test

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(8) NOT NULL AUTO_INCREMENT COMMENT 'ID',
`user_name` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '用户姓名',
`user_sex` char(1) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '用户性别',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=23 DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of t_user
-- ----------------------------
BEGIN;
INSERT INTO `t_user` VALUES (1, '刘备', '男');
INSERT INTO `t_user` VALUES (2, '孙尚香', '女');
INSERT INTO `t_user` VALUES (3, '周瑜', '男');
INSERT INTO `t_user` VALUES (4, '小乔', '女');
INSERT INTO `t_user` VALUES (5, '诸葛亮', '男');
INSERT INTO `t_user` VALUES (6, '黄月英', '女');
INSERT INTO `t_user` VALUES (7, '关羽', '男');
INSERT INTO `t_user` VALUES (8, '张飞', '男');
INSERT INTO `t_user` VALUES (9, '赵云', '男');
INSERT INTO `t_user` VALUES (10, '黄总', '男');
INSERT INTO `t_user` VALUES (11, '曹操', '男');
INSERT INTO `t_user` VALUES (12, '司马懿', '男');
INSERT INTO `t_user` VALUES (13, '貂蝉', '女');
INSERT INTO `t_user` VALUES (14, '吕布', '男');
INSERT INTO `t_user` VALUES (15, '马超', '男');
INSERT INTO `t_user` VALUES (16, '魏延', '男');
INSERT INTO `t_user` VALUES (17, '孟获', '男');
INSERT INTO `t_user` VALUES (18, '大乔', '女');
INSERT INTO `t_user` VALUES (19, '刘婵', '男');
INSERT INTO `t_user` VALUES (20, '姜维', '男');
INSERT INTO `t_user` VALUES (21, '廖化', '男');
INSERT INTO `t_user` VALUES (22, '关平', '男');
COMMIT;
SET FOREIGN_KEY_CHECKS = 1;

dbb_test2


SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0; -- ----------------------------
-- Table structure for t_hero
-- ----------------------------
DROP TABLE IF EXISTS `t_hero`;
CREATE TABLE `t_hero` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'ID',
`hero_code` varchar(32) DEFAULT NULL COMMENT '英雄编码',
`hero_name` varchar(20) DEFAULT NULL COMMENT '英雄名称',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8; -- ----------------------------
-- Records of t_hero
-- ----------------------------
BEGIN;
INSERT INTO `t_hero` VALUES (1, '001', '德玛西亚');
COMMIT; SET FOREIGN_KEY_CHECKS = 1;

构建项目,项目目录结构

pom 文件

<?xml version="1.0" encoding="UTF-8"?>
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.9.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>cn.zwqh</groupId>
<artifactId>spring-boot-mybatis-mulidatasource</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>spring-boot-mybatis-mulidatasource</name>
<description>spring-boot-mybatis-mulidatasource</description> <properties>
<java.version>1.8</java.version>
</properties> <dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency> <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency> <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency> <!-- 热部署模块 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional> <!-- 这个需要为 true 热部署才有效 -->
</dependency> <!-- mysql 数据库驱动. -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency> <!-- mybaits -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.0</version>
</dependency> <!-- alibaba的druid数据库连接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.20</version>
</dependency> <!-- pagehelper -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.2.12</version>
</dependency>
</dependencies> <build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build> </project>

这里使用了alibaba的druid数据库连接池,Druid 能够提供强大的监控和扩展功能。这里我们暂时只做简单的应用。

配置文件

#master 数据源配置
master.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
master.datasource.url=jdbc:mysql://127.0.0.1:3306/db_test?useUnicode=true&characterEncoding=UTF-8&useSSL=true
master.datasource.username=root
master.datasource.password=zwqh@0258
#slave 数据源配置
slave.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
slave.datasource.url=jdbc:mysql://127.0.0.1:3306/db_test2?useUnicode=true&characterEncoding=UTF-8&useSSL=true
slave.datasource.username=root
slave.datasource.password=zwqh@0258
#mybatis
mybatis.mapper-locations=classpath:/mapper/**/*Mapper.xml

数据源配置

MasterDataSourceConfig 对应数据库 db_test

@Configuration
@MapperScan(basePackages = "cn.zwqh.springboot.dao.master", sqlSessionFactoryRef = "masterSqlSessionFactory")
public class MasterDataSourceConfig {
@Value("${master.datasource.driver-class-name}")
private String driverClassName; @Value("${master.datasource.url}")
private String url; @Value("${master.datasource.username}")
private String username; @Value("${master.datasource.password}")
private String password; @Bean(name = "masterDataSource")
@Primary
public DataSource dataSource() {
DruidDataSource dataSource = new DruidDataSource();
dataSource.setDriverClassName(this.driverClassName);
dataSource.setUrl(this.url);
dataSource.setUsername(this.username);
dataSource.setPassword(this.password);
return dataSource;
} @Bean(name = "masterSqlSessionFactory")
@Primary
public SqlSessionFactory sqlSessionFactory(@Qualifier("masterDataSource") DataSource dataSource) throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(dataSource);
bean.setMapperLocations(
new PathMatchingResourcePatternResolver().getResources("classpath*:/mapper/master/*Mapper.xml"));
return bean.getObject();
} @Bean(name = "masterTransactionManager")
@Primary
public DataSourceTransactionManager transactionManager(@Qualifier("masterDataSource") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
} @Bean(name = "masterSqlSessionTemplate")
@Primary
public SqlSessionTemplate testSqlSessionTemplate(
@Qualifier("masterSqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
return new SqlSessionTemplate(sqlSessionFactory);
}
}

SlaveDataSourceConfig 对应数据库 db_test2

@Configuration
@MapperScan(basePackages = "cn.zwqh.springboot.dao.slave", sqlSessionFactoryRef = "slaveSqlSessionFactory")
public class SlaveDataSourceConfig {
@Value("${slave.datasource.driver-class-name}")
private String driverClassName; @Value("${slave.datasource.url}")
private String url; @Value("${slave.datasource.username}")
private String username; @Value("${slave.datasource.password}")
private String password; @Bean(name = "slaveDataSource")
public DataSource dataSource() {
DruidDataSource dataSource = new DruidDataSource();
dataSource.setDriverClassName(this.driverClassName);
dataSource.setUrl(this.url);
dataSource.setUsername(this.username);
dataSource.setPassword(this.password);
return dataSource;
} @Bean(name = "slaveSqlSessionFactory")
public SqlSessionFactory sqlSessionFactory(@Qualifier("slaveDataSource") DataSource dataSource) throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(dataSource);
bean.setMapperLocations(
new PathMatchingResourcePatternResolver().getResources("classpath*:/mapper/slave/*Mapper.xml"));
return bean.getObject();
} @Bean(name = "slaveTransactionManager")
public DataSourceTransactionManager transactionManager(@Qualifier("slaveDataSource") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
} @Bean(name = "slaveSqlSessionTemplate")
public SqlSessionTemplate testSqlSessionTemplate(
@Qualifier("masterSqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
return new SqlSessionTemplate(sqlSessionFactory);
}
}

多个数据源在使用的过程中必须指定主库,不然会报错。

@MapperScan(basePackages = "cn.zwqh.springboot.dao.slave") 指定对应 Dao 层的扫描路径。

dao 层和 xml 层

db_test 数据库的 dao 层在 cn.zwqh.springboot.dao.master 包下,db_test2 数据库的 dao 层在 cn.zwqh.springboot.dao.slave 包下。

UserDao

public interface UserDao {

	List<UserEntity> getAll();

}

HeroDao

public interface HeroDao {

	List<Hero> getAllHero();

}

db_test 数据库的 xml 层在 /mapper/master/ 文件路径下,db_test2 数据库的 xml 层在 /mapper/slave/ 文件路径下。

UserMapper.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.4//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.zwqh.springboot.dao.master.UserDao">
<resultMap type="cn.zwqh.springboot.model.UserEntity" id="user">
<id property="id" column="id"/>
<result property="userName" column="user_name"/>
<result property="userSex" column="user_sex"/>
</resultMap>
<!-- 获取所有用户 -->
<select id="getAll" resultMap="user">
select * from t_user
</select>
</mapper>

HeroMapper.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.4//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.zwqh.springboot.dao.slave.HeroDao">
<resultMap type="cn.zwqh.springboot.model.Hero" id="hero">
<id property="id" column="id"/>
<result property="heroCode" column="hero_code"/>
<result property="heroName" column="hero_name"/>
</resultMap>
<!-- 获取所有用户 -->
<select id="getAllHero" resultMap="hero">
select * from t_hero
</select>
</mapper>

测试

测试可以使用 SpringBootTest,也可以放到 Controller中,个人习惯用 Controller。

@RestController
@RequestMapping("/test")
public class TestController { @Autowired
private UserDao userDao;
@Autowired
private HeroDao heroDao; /**
* 查找所有用户
* @return
*/
@RequestMapping("/getAllUser")
public List<UserEntity> getAllUser(){
return userDao.getAll();
}
/**
* 查找所有英雄
* @return
*/
@RequestMapping("/getAllHero")
public List<Hero> getAllHero(){
return heroDao.getAllHero();
} }

浏览器直接访问:http://127.0.0.1:8080/test/ 加上相关测试路径即可。

总结

多数据源一般用于主从模式或者按业务分库。

示例代码

github

码云

非特殊说明,本文版权归 朝雾轻寒 所有,转载请注明出处.

原文标题:Spring Boot 2.X(五):MyBatis 多数据源配置

原文地址:https://www.zwqh.top/article/info/12

如果文章对您有帮助,请扫码关注下我的公众号,文章持续更新中...

Spring Boot 2.X(五):MyBatis 多数据源配置的更多相关文章

  1. spring boot(七):springboot+mybatis多数据源最简解决方案

    说起多数据源,一般都来解决那些问题呢,主从模式或者业务比较复杂需要连接不同的分库来支持业务.我们项目是后者的模式,网上找了很多,大都是根据jpa来做多数据源解决方案,要不就是老的spring多数据源解 ...

  2. Spring Boot 数据访问集成 MyBatis 与事物配置

    对于软件系统而言,持久化数据到数据库是至关重要的一部分.在 Java 领域,有很多的实现了数据持久化层的工具和框架(ORM).ORM 框架的本质是简化编程中操作数据库的繁琐性,比如可以根据对象生成 S ...

  3. Spring Boot 2.1.1.RELEASE 多数据源配置与使用

    有时候,一个系统的功能,需要两个或两个以上的数据库, 在Spring Boot 中要如何配置? How to? #primary primary.spring.datasource.jdbc-url= ...

  4. Spring Boot从入门到精通(五)多数据源配置实现及源码分析

    多数据源配置在项目软件中是比较常见的开发需求,Spring和Spring Boot中对此都有相应的解决方案可供大家参考.在Spring Boot中,如MyBatis.JdbcTemplate以及Jpa ...

  5. 07.深入浅出 Spring Boot - 数据访问之Mybatis(附代码下载)

    MyBatis 在Spring Boot应用非常广,非常强大的一个半自动的ORM框架. 代码下载:https://github.com/Jackson0714/study-spring-boot.gi ...

  6. spring boot / cloud (十五) 分布式调度中心进阶

    spring boot / cloud (十五) 分布式调度中心进阶 在<spring boot / cloud (十) 使用quartz搭建调度中心>这篇文章中介绍了如何在spring ...

  7. spring boot 2.0.0 + mybatis 报:Property 'sqlSessionFactory' or 'sqlSessionTemplate' are required

    spring boot 2.0.0 + mybatis 报:Property 'sqlSessionFactory' or 'sqlSessionTemplate' are required 无法启动 ...

  8. Spring Boot 整合 JPA 使用多个数据源

    介绍 JPA(Java Persistence API)Java 持久化 API,是 Java 持久化的标准规范,Hibernate 是持久化规范的技术实现,而 Spring Data JPA 是在 ...

  9. spring boot打印sql语句-mybatis

    spring boot打印sql语句-mybatis 概述 当自己编写的程序出现了BUG等等,找了很久 调试运行了几遍到mapper层也进去调试进了源码,非常麻烦 我就想打印出sql语句,好进行解决B ...

随机推荐

  1. Zabbix面试总结

    zabbix官方的一句话描述zabbix: 监视任何事情适用于任何IT基础架构,服务,应用程序和资源的解决方案 Monitor anythingSolutions for any kind of IT ...

  2. java路障CyclicBarrier

    当所有线程都执行到某行代码,才可已往下执行: package threadLock; import java.util.Random; import java.util.concurrent.Brok ...

  3. SVN中忘记上传自己写的工程,但是IP已经变了的解决方案

    苦于自己没有养成每天下班上传SVN的好习惯,第二天来又发现IP变了,只得把自己写的删掉,记录一下解决方法: 第一个红框中的svn://192.168.0.103/FH是前一天的IP链接地址,结果发现今 ...

  4. NOIP2002 1.级数求和

    这题目...... 题目:已知:Sn= 1+1/2+1/3+…+1/n.显然对于任意一个整数K,当n足够大的时候,Sn大于K.现给出一个整数K(1<=k<=15),要求计算出一个最小的n: ...

  5. Admiral(双向BFS + Hash)

    Problem Description Suppose that you are an admiral of a famous naval troop. Our naval forces have g ...

  6. Dart类型变量-表示信息

    Dart执行入口 Dart要求以main函数作为执行的入口 Dart的变量和类型 在Dart中可以用var或者具体的类型来声明一个变量.当使用var定义变量时,表示类型是由编译器推断决定.使用静态类型 ...

  7. 浅谈DanmakuView

      今天简单介绍一下开源的弹幕引擎---danmakuView   使用之前在build.gradle里面添加下面这一条(目前我使用的工具是AndroidStudio 3.1.2)   impleme ...

  8. 简说Python发展及其就业前景

    简说python 发展历史 Python是著名的"龟叔"Guido van Rossum在1989年圣诞节期间,为了打发无聊的圣诞节而编写的一个编程语言. python从ABC语言 ...

  9. YQL获取天气

    $(function () { $.getJSON("http://query.yahooapis.com/v1/public/yql?callback=?", { q: &quo ...

  10. Spring Boot(一) Hello World

    一.Spring Boot之我见     Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程.该框架使用了特定的方式来进行配置,从 ...