SpringBoot集成Mybatis实现对多数据源访问原理

 更新时间:2023年11月20日 08:55:25   作者:毅航  
本文主要分析讨论在SpringBoot应用中我们该如何配置SqlSessionFactoryBean对象,进而实现对多个不同的数据源的操纵,文章通过代码示例介绍的非常详细,需要的朋友可以参考下

注意❗:SpringBoot实际上连接多数据源的方式有很多种,也有很多成熟的技术选型,本文所提供的思路仅是为了帮助读者加深SqlSessionFactoryBean的理解和使用。

什么是多数据源

在现代软件架构中,多数据源指的是应用程序配置和连接到多个数据库实例的能力。这种架构允许应用程序根据不同的业务需求、数据类型或性能要求,与多个独立的数据库环境交互。在实现上,每个数据源都有自己的连接池、事务管理和数据访问对象。

上述专业定义可能有些晦涩难懂,其实你完全可以将多数据源的概念可以类比于一个大型学校里有多个图书馆和图书管理员的情况。每个图书馆(数据源)由不同的图书管理员(数据库管理系统)负责,管理着特定类型的书籍(数据)。

比如,一个图书馆可能专注于科学书籍,而另一个专门存放文学作品。这样的安排不仅提高了查找信息的效率——因为每个管理员都对自己的领域非常了解,同时还增强了安全性——因为可以为不同类型的数据设置不同级别的保护。

随着学校(业务)的发展,可能需要新的图书馆来容纳更多的书籍(数据),这时多图书馆的布局就显得尤为重要。总而言之,多数据源在软件应用中的作用就像这些图书馆和图书管理员一样,确保数据的有效管理、安全和高效访问。"

如上这张图就反映了应用中多数据源和单数据源之间的区别。接下来,我们就来分析在SpringBoot应用中,如何通过配置SqlSessionFactoryBean来实现多数据源的连接。

环境搭建

工欲善其事必先利其器,开始动手之前我们先来对构建案例所需的环境进行一个简单的介绍。后续案例所需的关键依赖如下:

  • SpringBoot的构建web应用的关键依赖:Spring-boot-starter-web
  • SpringBoot整合Mybatis的关键Startermybatis-spring-boot-starter
  • mysqljdbc连接依赖:mysql-connector-java
  • 数据连接池druiddruid-spring-boot-starter

项目整体结构如下:

  • dao1:数据源1所对应的数据Mapper接口;
  • dao2:数据源2所对应的数据Mapper接口;
  • config: 通过@Configuration标注的配置类信息。

除此之外,我们还需要准备两个数据源信息,在此笔者准了如下所示的test_dbtest_db1两个数据库,其内部均有一张t_user的数据表。

t_user数据表包含nametype两个字段信息。

实战双数据源配置

在开始之前,我们先来简单回顾下SpringBoot集成Mybatis时在连接单数据源时是如何进行配置的:

spring:
  datasource:
    username: root
    password: root
    # allowMultiQueries表示支持执行;间隔的多个sql nullCatalogMeansCurrent=true返回指定库涉及的表
    jdbc-url: jdbc:mysql://127.0.0.1:3306/test_db?characterEncoding=utf8&useSSL=false&serverTimezone=UTC&tcpKeepAlive=true&autoReconnect=true&allowMultiQueries=true&nullCatalogMeansCurrent=true
    driver-class-name: com.mysql.cj.jdbc.Driver
    # 使用的连接池的类型
    type: com.alibaba.druid.pool.DruidDataSource

在上述配置文件中,我们主要配置了如下内容:

  • 数据库URL (spring.datasource.url): 这是数据库服务器的地址和数据库名。它通常包含协议(例如jdbc:mysql:)、主机地址、端口号(对于MySQL,默认是3306),以及要连接的数据库名。例如: jdbc:mysql://localhost:3306/test_db
  • 用户名 (spring.datasource.username): 用于连接数据库的用户名。
  • 密码 (spring.datasource.password): 用于连接数据库的密码。
  • 驱动类名 (spring.datasource.driver-class-name): 这是JDBC驱动的完整类名,它用于告诉Spring Boot应用程序使用哪种数据库。例如,对于MySQL,通常是com.mysql.cj.jdbc.Driver

当我们配置多数据源时,配置文件需要做如下的修改:

spring:
# 数据源1
  primary:
    username: root
    password: root
    jdbc-url: jdbc:mysql://127.0.0.1:3306/test_db?characterEncoding=utf8&useSSL=false&serverTimezone=UTC&tcpKeepAlive=true&autoReconnect=true&allowMultiQueries=true&nullCatalogMeansCurrent=true
    driver-class-name: com.mysql.cj.jdbc.Driver
    # 使用的连接池的类型
    type: com.alibaba.druid.pool.DruidDataSource
# 数据源2
  slave:
    username: root
    password: root
    jdbc-url: jdbc:mysql://127.0.0.1:3306/test_db1?characterEncoding=utf8&useSSL=false&serverTimezone=UTC&tcpKeepAlive=true&autoReconnect=true&allowMultiQueries=true&nullCatalogMeansCurrent=true
    driver-class-name: com.mysql.cj.jdbc.Driver
    type: com.alibaba.druid.pool.DruidDataSource
   

此时,我们将之前配置文件中datasource改为了primary 和  slave,这样SpringBoot 就不再会为我们设定默认数据库。与此同时,我们将url改为了jdbc-url。这是因为 当只有单个数据源时,SpringBoot 会默认将url 映射为 jdbc-url 进行映射,进而保证我们获得数据源的成功注入。

此外,由于我们不再使用SpringBoot的默认配置来加载数据源,所以需要手动设置的数据源的连接地址,如果不进行修改,则会导致项目无法启动,进而出现 jdbcUrl is required with driverClassName 的异常。

处理好配置文件后,我们需要构建出DataSourceSqlSessionFactory从而实现对SqlSessionFactoryBean的定制化配置,其具体配置如下:

@Configuration
@MapperScan(basePackages = "com.example.dao1", sqlSessionFactoryRef = "sqlSessionFactory1")
public class DataSource1Config {

    @Bean
    @ConfigurationProperties(prefix = "spring.primary")
    public DataSource dataSourcePrimary() {
        return DataSourceBuilder.create().build();
    }

    @Bean
    public SqlSessionFactory sqlSessionFactory1() throws Exception {
        SqlSessionFactoryBean sessionFactoryBean = new SqlSessionFactoryBean();
        sessionFactoryBean.setDataSource(dataSourcePrimary());
        String locationPattern = "classpath*:/mapperPrimary/*.xml";
        PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        sessionFactoryBean.setMapperLocations(resolver.getResources(locationPattern));
        return sessionFactoryBean.getObject();
    }

    @Bean(name = "sqlSessionTemplate1")
    public SqlSessionTemplate sqlSessionTemplate1(@Qualifier("sqlSessionFactory1") SqlSessionFactory sqlSessionFactory) {
        return new SqlSessionTemplate(sqlSessionFactory);
    }
}

当我们期待使用Mybatis操作多数据源时,对于不同的数据源,我们都需要定义不同的Mapper接口和XML映射文件,以确保最终生成的Mapper实现类可以操纵不同的数据源信息。所以,其中的dataSourcePrimary就是为了加载dataSourcePrimary指定的数据源信息,确保构建的数据源最终连接到Primary中指定的数据库信息。而在sqlSessionFactory的构建中,则主要通过SqlSessionFactoryBean来构建出一个SqlSessionFactory并注入容器,而在这一过程中需要设定Mapper接口所对应的配置文件。

slave的配置可参考DataSource1Config进行配置,在此便不进行赘述。接下来,我们来看下最终的效果:

@RestController
@RequestMapping("/data")
@Slf4j
public class DataSourceController {

    @Autowired
    private User1Mapper userMapper;
    @Autowired
    private User2Mapper user2Mapper;

    @GetMapping("/get-user1/{name}")
    public User getUserFromTestDb(@PathVariable("name") String userName) {
        return userMapper.selectUser(userName);
    }

    @GetMapping("/get-user2/{name}")
    public User getUserFromTestDb2(@PathVariable("name") String userName) {
        return user2Mapper.selectUser(userName);
    }

}
  • getUserFromTestDb用于从数据源test_db获取数据
  • getUserFromTestDb2用于从数据源test_db1获取数据

最终效果如下:

访问数据源1

访问数据源2

总结

接下来,我们对上述程序用到的组件进行一个简要的总结和回顾

  • 数据源(DataSource)。数据源是数据库连接的工厂。在Spring中,DataSource对象负责提供数据库连接。当配置多个数据源时,每个数据源都对应不同的数据库连接信息。例如,一个数据源可能连接到数据库test_db,而另一个连接到数据库test_db1

  • Mybatis的SqlSessionFactorySqlSessionFactoryMybatis中的一个核心组件,它负责创建SqlSessionSqlSession提供了执行SQL命令、获取映射器和管理事务的方法。在配置多个数据源的情况下,每个数据源都需要有对应的SqlSessionFactory,以确保SQL操作能够针对正确的数据库执行。

  • @MapperScan 注解的使用。该注解用于指定哪些包中的接口应该被Mybatis识别为映射器(Mapper)。在多数据源配置中,可以使用不同的@MapperScan注解来指定不同数据源的映射器。

更进一步,SpringBoot集成Mybatis实现多数据源的基本流程如下:

  • 为每个数据源定义独立的配置,包括DataSource、SqlSessionFactory
  • 使用@MapperScan为每个数据源指定Mapper接口的位置。
  • 将配置好的SqlSessionFactory交由SpringBoot容器进行管理

这样,当应用程序运行时,只需要注入不同数据源对应的Mapper即可访问不同的数据库,而无需担心数据源之间的冲突和干扰。

最后,希望本文对你对有助于加深理解SpringBoot集成Mybatis的原理。

以上就是SpringBoot集成Mybatis实现对多数据源访问原理的详细内容,更多关于SpringBoot Mybatis多数据源访问的资料请关注脚本之家其它相关文章!

相关文章

  • Java中初始化List集合的八种方式汇总

    Java中初始化List集合的八种方式汇总

    List 是 Java 开发中经常会使用的集合,下面这篇文章主要给大家介绍了关于Java中初始化List集合的八种方式,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-06-06
  • Struts2学习笔记(2)-路径问题解决

    Struts2学习笔记(2)-路径问题解决

    本文主要介绍Struts2的路径问题,尽量不要使用相对路径,使用相对路径会让路径问题变得很繁琐很麻烦,推荐使用绝对路径,希望能给大家做一个参考。
    2016-06-06
  • Spring常用注解及自定义Filter的实现

    Spring常用注解及自定义Filter的实现

    这篇文章主要介绍了Spring常用注解及自定义Filter的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-08-08
  • Java实现将数据导出为Word文档的方法步骤

    Java实现将数据导出为Word文档的方法步骤

    我们在开发一些系统的时候,例如OA系统,经常能遇到将审批单数据导出为word和excel文档的需求,导出为excel是比较简单的,但是word文档的格式不像表格那样可以轻松的定位,所以本文给大家介绍了Java怎样实现将数据导出为Word文档,需要的朋友可以参考下
    2025-01-01
  • Java遍历集合的三种方式

    Java遍历集合的三种方式

    本文主要对于遍历集合获取其对象,总结的三种简单的方式进行介绍,文章中举了两个案例进行对比,具有很好的参考价值,下面就跟小编一起来看下吧
    2016-12-12
  • Spring Cloud Gateway不同频率限流的解决方案(每分钟,每小时,每天)

    Spring Cloud Gateway不同频率限流的解决方案(每分钟,每小时,每天)

    SpringCloud Gateway 是 Spring Cloud 的一个全新项目,它旨在为微服务架构提供一种简单有效的统一的 API 路由管理方式。这篇文章主要介绍了Spring Cloud Gateway不同频率限流(每分钟,每小时,每天),需要的朋友可以参考下
    2020-10-10
  • Spring boot2.0 实现日志集成的方法(2)

    Spring boot2.0 实现日志集成的方法(2)

    这篇文章主要介绍了Spring boot2.0 实现日志集成的方法,上一章讲解了spring boot日志简单集成,这篇我们将日志进行分类,常规日志、异常日志、监控日志等,需要将日志输出到不同的文件,具体内容需要的小伙伴可以参考一下
    2022-04-04
  • form表单回写技术java实现

    form表单回写技术java实现

    这篇文章主要为大家详细介绍了java实现form表单回写技术的相关资料,需要的朋友可以参考下
    2016-04-04
  • SpringBoot Mail邮件任务详情

    SpringBoot Mail邮件任务详情

    这篇文章主要介绍了SpringBoot Mail邮件任务详情,文章通过spring-boot-starter-mail包展开详细内容,需要的小伙伴可以参考一下
    2022-05-05
  • 背包问题-动态规划java实现的分析与代码

    背包问题-动态规划java实现的分析与代码

    这篇文章主要给大家介绍了关于背包问题动态规划java实现的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-12-12

最新评论