SpringBoot从入门到精通(二十三)Mybatis系列之——实现Mybatis多数据源配置

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
云数据库 RDS MySQL,高可用系列 2核4GB
简介: 之前介绍了Spring Boot 整合mybatis 使用注解方式配置的方式实现增删改查以及一些复杂自定义的sql 语句 。想必大家对spring boot 项目中,如何使用mybatis 有了一定的了解。但在很多业务场景下,我们需要在一个项目中配置多个数据源来实现业务逻辑,例如:现有电商业务,商品和库存数据分别放在不同的数据库中,这就要求我们的系统架构支持同时配置多个数据源实现相关业务操作。那么Spring Boot 如何应对这种多数据源的场景呢?其实,在 Spring Boot 项目中配置多数据源十分便捷。接下来就聊一聊 Spring Boot 整合mybatis 实现多数据源的相关配置。

之前介绍了Spring Boot 整合mybatis 使用注解方式配置的方式实现增删改查以及一些复杂自定义的sql 语句 。想必大家对spring boot 项目中,如何使用mybatis 有了一定的了解。但在很多业务场景下,我们需要在一个项目中配置多个数据源来实现业务逻辑,例如:现有电商业务,商品和库存数据分别放在不同的数据库中,这就要求我们的系统架构支持同时配置多个数据源实现相关业务操作。那么Spring Boot 如何应对这种多数据源的场景呢?其实,在 Spring Boot 项目中配置多数据源十分便捷。接下来就聊一聊 Spring Boot 整合mybatis 实现多数据源的相关配置。


一、配置数据库

首先在系统配置文件中,需要配置多个数据源,即在application.properties 文件中增加如下配置:

# mybatis 多数据源配置
# 数据库1的配置
spring.datasource.test1.driver-class-name = com.mysql.jdbc.Driver
spring.datasource.test1.jdbc-url = jdbc:mysql://localhost:3306/zwz_test?useUnicode=true&characterEncoding=utf-8&useSSL=false
spring.datasource.test1.username = root
spring.datasource.test1.password = root
# 数据库2的配置
spring.datasource.test2.driver-class-name = com.mysql.jdbc.Driver
spring.datasource.test2.jdbc-url = jdbc:mysql://localhost:3306/zwz_test2?useUnicode=true&characterEncoding=utf-8&useSSL=false
spring.datasource.test2.username = root
spring.datasource.test2.password = root

注意:

1、这里配置的是两个一样的数据库zwz_test 和zwz_test2。

2、数据库连接的配置使用jdbc-url , 不是之前的url ,这点需要注意。

 

二、数据源配置类

1、主数据源配置类

在config 包中,创建 DataSource1Config 类。此类配置主数据源。

package com.weiz.config;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
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 org.springframework.jdbc.datasource.DataSourceTransactionManager;
import javax.sql.DataSource;
@Configuration
@MapperScan(basePackages = "com.weiz.mapper.test1", sqlSessionFactoryRef = "test1SqlSessionFactory")
public class DataSource1Config {
        @Bean(name = "test1DataSource")
        @ConfigurationProperties(prefix = "spring.datasource.test1")
        @Primary
        public DataSource testDataSource() {
                return DataSourceBuilder.create().build();
        }
        @Bean(name = "test1SqlSessionFactory")
        @Primary
        public SqlSessionFactory testSqlSessionFactory(@Qualifier("test1DataSource") DataSource dataSource) throws Exception {
                SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
                bean.setDataSource(dataSource);
                return bean.getObject();
        }
        @Bean(name = "test1TransactionManager")
        @Primary
        public DataSourceTransactionManager testTransactionManager(@Qualifier("test1DataSource") DataSource dataSource) {
                return new DataSourceTransactionManager(dataSource);
        }
        @Bean(name = "test1SqlSessionTemplate")
        @Primary
        public SqlSessionTemplate testSqlSessionTemplate(@Qualifier("test1SqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
                return new SqlSessionTemplate(sqlSessionFactory);
        }
}

 

2、配置其他数据源

在config 包中,创建DataSource2Config 类。此类配置其他普通数据源。

package com.weiz.config;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
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 org.springframework.jdbc.datasource.DataSourceTransactionManager;
import javax.sql.DataSource;
@Configuration
@MapperScan(basePackages = "com.weiz.mapper.test2", sqlSessionFactoryRef = "test2SqlSessionFactory")
public class DataSource2Config {
        @Bean(name = "test2DataSource")
        @ConfigurationProperties(prefix = "spring.datasource.test2")
        public DataSource testDataSource() {
                return DataSourceBuilder.create().build();
        }
        @Bean(name = "test2SqlSessionFactory")
        public SqlSessionFactory testSqlSessionFactory(@Qualifier("test2DataSource") DataSource dataSource) throws Exception {
                SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
                bean.setDataSource(dataSource);
                return bean.getObject();
        }
        @Bean(name = "test2TransactionManager")
        public DataSourceTransactionManager testTransactionManager(@Qualifier("test2DataSource") DataSource dataSource) {
                return new DataSourceTransactionManager(dataSource);
        }
        @Bean(name = "test2SqlSessionTemplate")
        public SqlSessionTemplate testSqlSessionTemplate(@Qualifier("test2SqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
                return new SqlSessionTemplate(sqlSessionFactory);
        }
}

说明, DataSource1Config 和  DataSource2Config 即是相关的主数据源配置类和普通数据源配置类。

com.weiz.mapper.test1 为 扫描的mapper的路径。

可以看到两个数据源都配置的各自的DataSource、SqlSessionFactory、TransactionManager和SqlSessionTemplate 。

 

虽然两个类看着差不多,但是需要特别注意以下几点

  1、主数据源配置需要加@Primary 注解,其他普通数据源不能加这个注解,否则会报错,复制的时候小心。

  2、各个数据源配置的 basePackages 扫描路径需要配置正确。配置错了不会出异常,但是运行的时候,会找错数据库。

 

3、如何调用

首先,创建com.weiz.mapper.test1 和 com.weiz.mapper.test2 包,将之前的UserMapper ,重名命为User1Mapper 和User2Mapper 复制到相应的包中。

然后,UserServiceImpl 分别注入两个不同的 Mapper,想操作哪个数据源就使用哪个数据源的 Mapper 进行操作处理。

package com.weiz.service.impl;
import com.weiz.mapper.test1.User1Mapper;
import com.weiz.mapper.test2.User2Mapper;
import com.weiz.pojo.User;
import com.weiz.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class UserServiceImpl implements UserService {
    @Autowired
    private User1Mapper user1Mapper;
    @Autowired
    private User2Mapper user2Mapper;
    @Override
    public int saveUser(User user) {
        user1Mapper.insert(user);
        return user2Mapper.insert(user);
    }
    @Override
    public int updateUser(User user) {
        user1Mapper.updateByPrimaryKey(user);
        return user2Mapper.updateByPrimaryKey(user);
    }
    @Override
    public int deleteUser(String userId) {
        user1Mapper.deleteByPrimaryKey(userId);
        return user2Mapper.deleteByPrimaryKey(userId);
    }
    @Override
    public User queryUserById(String userId) {
        user1Mapper.selectByPrimaryKey(userId);
        return user2Mapper.selectByPrimaryKey(userId);
    }
}

这里是一个简单的测试程序,实际项目中是根据实际的业务,调用不同的mapper 实现的,或者通过注解配置,动态切换数据源。

 

三、验证测试

启动项目,浏览器中输入如下地址: http://localhost:8088/mybatis/saveuser ,可以看到两个数据库中,都增加了一条用户信息。

数据库 zwz_test 中 用户表sys_user 增加了一条记录。

image.png

 

数据库 zwz_test2 中 用户表sys_user 也增加了一条同样的记录。

image.png

 

四、可能会遇到的坑

1、数据库连接的配置使用jdbc-url , 不是之前的url 。这点需要注意。

2、主数据源配置需要加@Primary 注解,其他普通数据源不能加这个注解,否则会报错,复制的时候小心。

3、各个数据源配置的 basePackages 扫描路径需要配置正确。配置错了不会出异常,但是运行的时候,会找错数据库。

4、如果Mybatis使用的是xml 配置版,xml位置需要在每个config显示置顶位置。

 

最后

以上,就把Spring Boot整合Mybatis,实现多数据源配置的功能介绍完了。操作看似简单,其实还是得小心仔细。不然很容易出错。

此外配置多数据源之后,还涉及到数据源切换的问题,网上有很多种方法,比较流行的就是druid框架实现多数据源切换。这个后面再讲吧。

还有,这里没有使用事务,如果采用事务需要分别配置每个数据源的事务,并采用事务性注解进行统一管理。这里不细说大家自己研究吧。

这个系列课程的完整源码,也会提供给大家。大家关注我的微信公众号(架构师精进),回复:springboot源码。获取这个系列课程的完整源码。



推荐阅读:

SpringBoot从入门到精通(二十二)使用Swagger2优雅构建 RESTful API文档

SpringBoot从入门到精通(二十一)如何优雅的设计 RESTful API 接口版本号,实现 API 版本控制!

SpringBoot从入门到精通(二十)快速构建RESTful Web API 服务

SpringBoot从入门到精通(十九)使用注解实现动态Sql、参数传递

SpringBoot从入门到精通(十八)Mybatis系列之——使用注解的方式实现后台管理功能

SpringBoot从入门到精通(十七)MyBatis系列之——创建自定义mapper 实现多表关联查询!

SpringBoot从小白到精通(十六)使用pagehelper实现分页查询功能

SpringBoot从小白到精通(十五)实现开发环境热部署

SpringBoot从小白到精通(十四)使用JdbcTemplate操作数据库,配置多数据源!

SpringBoot从小白到精通(十三)如何实现事务保存

SpringBoot从小白到精通(十二)logback日志配置

SpringBoot从小白到精通(十一)统一异常处理

SpringBoot从小白到精通(十)使用Interceptor拦截器,一学就会!

SpringBoot从小白到精通(九)使用@Async实现异步执行任务

SpringBoot从小白到精通(八)熟悉@EnableScheduling,一秒搞定定时任务

SpringBoot从小白到精通(七)使用Redis实现高速缓存架构

SpringBoot从小白到精通(六)使用Mybatis实现增删改查【附详细步骤】

SpringBoot从小白到精通(五)Thymeleaf的语法及常用标签

SpringBoot从小白到精通(四)Thymeleaf页面模板引擎

SpringBoot从小白到精通(三)系统配置及自定义配置

SpringBoot从小白到精通(二)如何返回统一的数据格式

SpringBoot从小白到精通(一)如何快速创建SpringBoot项目

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
1月前
|
Java 开发者 微服务
手写模拟Spring Boot自动配置功能
【11月更文挑战第19天】随着微服务架构的兴起,Spring Boot作为一种快速开发框架,因其简化了Spring应用的初始搭建和开发过程,受到了广大开发者的青睐。自动配置作为Spring Boot的核心特性之一,大大减少了手动配置的工作量,提高了开发效率。
50 0
|
2月前
|
Java API 数据库
构建RESTful API已经成为现代Web开发的标准做法之一。Spring Boot框架因其简洁的配置、快速的启动特性及丰富的功能集而备受开发者青睐。
【10月更文挑战第11天】本文介绍如何使用Spring Boot构建在线图书管理系统的RESTful API。通过创建Spring Boot项目,定义`Book`实体类、`BookRepository`接口和`BookService`服务类,最后实现`BookController`控制器来处理HTTP请求,展示了从基础环境搭建到API测试的完整过程。
58 4
|
2月前
|
Java API 数据库
Spring Boot框架因其简洁的配置、快速的启动特性及丰富的功能集而备受开发者青睐
本文通过在线图书管理系统案例,详细介绍如何使用Spring Boot构建RESTful API。从项目基础环境搭建、实体类与数据访问层定义,到业务逻辑实现和控制器编写,逐步展示了Spring Boot的简洁配置和强大功能。最后,通过Postman测试API,并介绍了如何添加安全性和异常处理,确保API的稳定性和安全性。
41 0
|
1天前
|
NoSQL Java Redis
Spring Boot 自动配置机制:从原理到自定义
Spring Boot 的自动配置机制通过 `spring.factories` 文件和 `@EnableAutoConfiguration` 注解,根据类路径中的依赖和条件注解自动配置所需的 Bean,大大简化了开发过程。本文深入探讨了自动配置的原理、条件化配置、自定义自动配置以及实际应用案例,帮助开发者更好地理解和利用这一强大特性。
28 14
|
23天前
|
缓存 IDE Java
SpringBoot入门(7)- 配置热部署devtools工具
SpringBoot入门(7)- 配置热部署devtools工具
41 1
SpringBoot入门(7)- 配置热部署devtools工具
|
1月前
|
缓存 IDE Java
SpringBoot入门(7)- 配置热部署devtools工具
SpringBoot入门(7)- 配置热部署devtools工具
43 2
 SpringBoot入门(7)- 配置热部署devtools工具
|
17天前
|
缓存 Java 数据库连接
深入探讨:Spring与MyBatis中的连接池与缓存机制
Spring 与 MyBatis 提供了强大的连接池和缓存机制,通过合理配置和使用这些机制,可以显著提升应用的性能和可扩展性。连接池通过复用数据库连接减少了连接创建和销毁的开销,而 MyBatis 的一级缓存和二级缓存则通过缓存查询结果减少了数据库访问次数。在实际应用中,结合具体的业务需求和系统架构,优化连接池和缓存的配置,是提升系统性能的重要手段。
34 4
|
17天前
|
SQL Java 数据库连接
spring和Mybatis的各种查询
Spring 和 MyBatis 的结合使得数据访问层的开发变得更加简洁和高效。通过以上各种查询操作的详细讲解,我们可以看到 MyBatis 在处理简单查询、条件查询、分页查询、联合查询和动态 SQL 查询方面的强大功能。熟练掌握这些操作,可以极大提升开发效率和代码质量。
31 3
|
22天前
|
Java 数据库连接 数据库
spring和Mybatis的逆向工程
通过本文的介绍,我们了解了如何使用Spring和MyBatis进行逆向工程,包括环境配置、MyBatis Generator配置、Spring和MyBatis整合以及业务逻辑的编写。逆向工程极大地提高了开发效率,减少了重复劳动,保证了代码的一致性和可维护性。希望这篇文章能帮助你在项目中高效地使用Spring和MyBatis。
14 1
|
25天前
|
存储 前端开发 JavaScript
springboot中路径默认配置与重定向/转发所存在的域对象
Spring Boot 提供了简便的路径默认配置和强大的重定向/转发机制,通过合理使用这些功能,可以实现灵活的请求处理和数据传递。理解并掌握不同域对象的生命周期和使用场景,是构建高效、健壮 Web 应用的关键。通过上述详细介绍和示例,相信读者能够更好地应用这些知识,优化自己的 Spring Boot 应用。
26 3