【Springboot】Springboot + Mybatis-plus配置多个数据源实现

0 导言

本文主要介绍使用Springboot框架配置多个数据源。

使用的主要框架以及数据库版本(已测试通过):

Springboot 3.2.1

Mybatis-plus 3.5.4.1

MySQL 8.0.30

1 实现(以两个数据源为例)

1.1 依赖配置

和单一数据源配置无区别

    <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.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.30</version>
        </dependency>

        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.5.4.1</version>
            <exclusions>
                <exclusion>
                    <artifactId>mybatis-spring</artifactId>
                    <groupId>org.mybatis</groupId>
                </exclusion>
            </exclusions>
        </dependency>
      
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>3.0.3</version>
        </dependency>

        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-generator</artifactId>
            <version>3.5.4.1</version>
        </dependency>

        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-core</artifactId>
            <version>3.5.4.1</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
    </dependencies>

1.2 yml配置

数据库相关配置:

spring:
  datasource:
    db-article:
      jdbc-url: jdbc:mysql://localhost:3306/leadnews_article?useSSL=false&useUnicode=true&characterEncoding=utf8&allowPublicKeyRetrieval=true
      username: root
      password: 123456
      driver-class-name: com.mysql.cj.jdbc.Driver
    db-user:
      jdbc-url: jdbc:mysql://localhost:3306/leadnews_user?useSSL=false&useUnicode=true&characterEncoding=utf8&allowPublicKeyRetrieval=true
      username: root
      password: 123456
      driver-class-name: com.mysql.cj.jdbc.Driver

放一张图来比较配置一个数据源和配置多个数据源的不同

在这里插入图片描述

  1. 为每个数据库起个名字。注意如果想使用连接符,不要使用下划线 ‘_’,虽然写的时候没错误,但是编译时会报错。
  2. url改成jdbc-url

1.3 配置数据源

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;

/**
 * 数据源配置
 */
@Configuration
public class DataSourceConfig {
    @Primary
    @Bean(name = "db_article")
    @ConfigurationProperties(prefix = "spring.datasource.db-article")
    public DataSource dBSrcArticle() {
        return DataSourceBuilder.create().build();
    }

    @Primary
    @Bean(name = "db_user")
    @ConfigurationProperties(prefix = "spring.datasource.db-user")
    public DataSource dBSrcUser() {
        return DataSourceBuilder.create().build();
    }
}

注意要加上Primary注解。

配置SqlSessionFactory

import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;

import javax.sql.DataSource;

/**
 * 数据库leadnews_article
 */
@Configuration
@MapperScan(basePackages = {"com.mapper.article"}, sqlSessionFactoryRef = "sqlSessionFactoryArticle")
public class DBSrcArticle {
    @Bean
    public SqlSessionFactory sqlSessionFactoryArticle(@Qualifier("db_article") DataSource dataSource) throws Exception {
        MybatisSqlSessionFactoryBean sqlSessionFactory = new MybatisSqlSessionFactoryBean();
        sqlSessionFactory.setDataSource(dataSource);
        sqlSessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver()
                .getResources("classpath:**/*.xml"));
        return sqlSessionFactory.getObject();
    }

    @Bean
    public SqlSessionTemplate sqlSessionTemplateArticle(@Qualifier("sqlSessionFactoryArticle") SqlSessionFactory sqlSessionFactory) throws Exception {
        return new SqlSessionTemplate(sqlSessionFactory);
    }
}
import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;

import javax.sql.DataSource;

/**
 * 数据库leadnews_user
 */
@Configuration
@MapperScan(basePackages = {"com.mapper.user"}, sqlSessionFactoryRef = "sqlSessionFactoryUser")
public class dBSrcUser {
    @Bean
    @Primary
    public SqlSessionFactory sqlSessionFactoryUser(@Qualifier("db_user") DataSource dataSource) throws Exception {
        MybatisSqlSessionFactoryBean sqlSessionFactory = new MybatisSqlSessionFactoryBean();
        sqlSessionFactory.setDataSource(dataSource);
        sqlSessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver()
                .getResources("classpath:**/*.xml"));
        return sqlSessionFactory.getObject();
    }

    @Bean
    @Primary
    public SqlSessionTemplate sqlSessionTemplateUser(@Qualifier("sqlSessionFactoryUser") SqlSessionFactory sqlSessionFactory) throws Exception {
        return new SqlSessionTemplate(sqlSessionFactory);
    }
}

说明:

  1. 两个数据源需要配置两个sqlSessionFactory

  2. 这里不同的数据源的sqlSessionFactory的名字不可以相同,且在使用时必须通过名字指名使用的是哪一个数据源。且需要标注一个为主数据源,即加上 @Primary注解

  3. 单一数据源时所有的mapper文件都直接放置在mapper目录下,多个数据源则要对这些mapper文件进行分离,以此来区分使用的数据库,如此时的mapper文件层级如下图,所以此时注解 @MapperScanbasepackagessqlSessionFactoryRef指定的SqlSessionFactory是一一对应的。

    在这里插入图片描述

1.4 修改启动类

@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
@MapperScan(basePackages = {"com.rain.mapper.article"}, sqlSessionFactoryRef = "sqlSessionFactoryArticle")
@MapperScan(basePackages = {"com.rain.mapper.user"}, sqlSessionFactoryRef = "sqlSessionFactoryUser")

在启动类上加上以上三个注解即可。

  1. exclude = {DataSourceAutoConfiguration.class},排除这个的主要原因是我们使用了自定义的数据源,而不是使用Springboot服务启动时对于数据源配置的自动导入。
  2. 这里再次使用了MapperScan注解,与配置SqlSessionFactory时使用的没有什么区别。在我自己测试的过程中,只在启动类加上MapperScan注解即可。如果启动类上不加,则会出现两种错误:

​ a. 如果没有此注解,则运行失败:

在这里插入图片描述

​ b. 如果不指名对应关系或对应关系错误,则会出现数据库与数据库中表不匹配的情况,即系统认为只有一个数据源,报错信息如下:

在这里插入图片描述

article表自然在user库中不存在。

2 其它问题

2.1 Mybatis & Mybatis-plus

在配置SqlSessionFactory时需要注意,如果使用的是Mybatis-plus,则按照1中实现即可,如果使用的是Mybatis,则

 //MybatisSqlSessionFactoryBean sqlSessionFactory = new MybatisSqlSessionFactoryBean();
//Mybatis使用下面这个
SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();

如果不正确使用,会出现无法正常使用BaseMapper的问题

报错如BindingException:Invalid bound statement (not found) XXX selectList

2.2 @Primary

@Primary注解可以标注出有多个候选者有资格自动装配单值依赖项时,优先考虑的Bean对象,如果没有或者标了多个都会出现错误

3 总结

本文讲述了如何实现多数据源配置。

除了这种方式,还有很多其它方式,比如Mybatis-plus中提供的动态数据源SpringBoot的starter:dynamic-datasource-spring-boot-starter来实现,再比如使用ThreadLocal+AbstractRoutingDataSource的方式实现,有兴趣之后自行探索。

ps:运行项目中发现mybatis-plus的图案还是很可爱的

在这里插入图片描述

  • 27
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值