java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > SpringBoot Mybatis多数据源访问

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

作者:毅航

本文主要分析讨论在SpringBoot应用中我们该如何配置SqlSessionFactoryBean对象,进而实现对多个不同的数据源的操纵,文章通过代码示例介绍的非常详细,需要的朋友可以参考下

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

什么是多数据源

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

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

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

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

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

环境搭建

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

项目整体结构如下:

除此之外,我们还需要准备两个数据源信息,在此笔者准了如下所示的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

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

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

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);
    }

}

最终效果如下:

访问数据源1

访问数据源2

总结

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

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

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

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

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

您可能感兴趣的文章:
阅读全文