Spring Boot 教程

Spring Boot 笔记

Spring Boot 如何配置多个 DB 数据源

Spring Boot 笔记 Spring Boot 笔记


Spring Boot 基于 MyBatis 配置多个 DB 数据源,这里基于 jdk 1.8,引入 spring boot 和 mybatis 的集成包 org.mybatis.spring.boot 即可。具体配置步骤如下。

引入相关 jar 包

先后引入 db 相关的 jar 包(这里以 mysql 为例),再引入 spring boot jdbc 公共包与  mybatis 的集成包。

如果项目是 maven 项目,示例如下:

<!-- mysql jar 包 -->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.46</version>
</dependency>

<!-- 用 starter 导入 jdbc -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jdbc</artifactId>
    <version>2.1.8.RELEASE</version>
</dependency>

<!-- 用 starter 导入 mybatis 与 spring boot 集成包 -->
<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>2.0.0</version>
</dependency>

如果是 gradle 项目,示例如下:

compile group: 'mysql', name: 'mysql-connector-java', version: '5.1.46'
compile group: 'org.springframework.boot', name: 'spring-boot-starter-jdbc'
compile group: 'org.mybatis.spring.boot', name: 'mybatis-spring-boot-starter', version: '2.0.0'

配置数据源

配置多数据源,首先要禁调 spring boot 默认的单数据源配置,然后在 application.yml 里自定义配置多个数据源,最后创建基于注解的数据源配置类。

禁止默认单数据源配置

spring boot 默认情况下,它会读取 application.yml 文件的 spring.datasource.* 属性,并自动配置单数据源,需要通过以下方式禁止这一默认行为,具体如下:

@SpringBootApplication
@EnableAutoConfiguration(exclude = {
        DataSourceAutoConfiguration.class
})
public class MainApplication {
    
    public static void main(String[] args) {
       
        SpringApplication.run(MainApplication.class, args);
        
    }
}

在 main 方法所在的类上面增加 @EnableAutoConfiguration 注解,并在其中排除(exclude)DataSourceAutoConfiguration 类即可。

application.yml 配置

在 application.yml 里配置多个 db 数据源,名字无所谓,只需要不和 spring 默认的配置参数重名就可以,笔者以 datasource 作为前缀,具体如下:

datasource:
  db1:
    jdbcUrl: jdbc:mysql://xxx:xxx/db1?useUnicode=true&characterEncoding=utf8
    username: xxx
    password: xxx
    driverClassName: com.mysql.jdbc.Driver
  db2:
    jdbcUrl: jdbc:mysql://xxx:xxx/db2?useUnicode=true&characterEncoding=utf8
    username: xxx
    password: xxx
    driverClassName: com.mysql.jdbc.Driver

其中 db1 和 db2 表示自定义的数据源名称。

基于注解的数据库配置类

以一个 db1 对应的配置类为例,创建如下类:

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.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;

import javax.sql.DataSource;

@Configuration
@MapperScan(basePackages = {"xxx.xxx.dao.db1"}, sqlSessionTemplateRef = "db1SqlSessionTemplate")
public class DbReadConfig {

    @Bean(name = "db1DataSource")
    @ConfigurationProperties("datasource.db1")
    public DataSource dataSource() {
        return DataSourceBuilder.create().build();
    }

    @Bean(name = "db1SqlSessionFactory")
    public SqlSessionFactory sqlSessionFactory(@Qualifier("db1DataSource") DataSource dataSource) {
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
        sqlSessionFactoryBean.setDataSource(dataSource);
        ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();
        try {
          sqlSessionFactoryBean.setMapperLocations(resourcePatternResolver.getResources("classpath*:xxx/xxx/xxx/dao/db1/*/mapper/*.xml"));
            return sqlSessionFactoryBean.getObject();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    @Bean(name = "db1DataSourceTransactionManager")
    public DataSourceTransactionManager dataSourceTransactionManager(@Qualifier("db1DataSource") DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }

    @Bean(name = "db1SqlSessionTemplate")
    public SqlSessionTemplate sqlSessionTemplate(@Qualifier("db1SqlSessionFactory") SqlSessionFactory sqlSessionFactory) {
        return new SqlSessionTemplate(sqlSessionFactory);
    }
}

基于 mybatis 的映射文件要放在 xxx/xxx/xxx/dao/db1/*/mapper/ 下,如上创建类中指定的路径。 

配置多少个数据源,按照如上示例,创建多个配置类即可。