SpringBoot+Mybatis多數(shù)據(jù)源配置

現(xiàn)在一般的應(yīng)用都會(huì)有多個(gè)數(shù)據(jù)源.SpringBoot結(jié)合Mybatis的使用可以大大方便開發(fā)者對(duì)SQL的開發(fā).所以掌握SpringBoot+Mybatis多數(shù)據(jù)源的配置非常重要.

現(xiàn)將測(cè)試通過(guò)的多數(shù)據(jù)源配置整理如下.

框架版本

序號(hào) 框架 版本
1 spring-boot 1.5.4.RELEASE
2 mybatis-spring-boot-starter 1.3.1

相關(guān)POM.xml配置

<parent>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-parent</artifactId>
  <version>1.5.4.RELEASE</version>
  <relativePath /> <!-- lookup parent from repository -->
</parent>


<properties>
  <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

<dependencies>

  <!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
  <dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.38</version>
  </dependency>
  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
  </dependency>
    <!--<dependency>-->
        <!--<groupId>org.springframework.boot</groupId>-->
        <!--<artifactId>spring-boot-starter-data-jpa</artifactId>-->
    <!--</dependency>-->
    <!--<dependency>-->
        <!--<groupId>org.springframework.boot</groupId>-->
        <!--<artifactId>spring-boot-starter-jdbc</artifactId>-->
    <!--</dependency>-->
  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
  </dependency>
  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
  </dependency>
    <dependency>
        <groupId>org.mybatis.spring.boot</groupId>
        <artifactId>mybatis-spring-boot-starter</artifactId>
        <version>1.3.1</version>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
    </dependency>
</dependencies>

配置DataSource

對(duì)于多個(gè)數(shù)據(jù)源(如多個(gè)庫(kù), 多個(gè)schema等), 一般都要用不同的連接池對(duì)應(yīng)不同的數(shù)據(jù)源.
因此首先需要配置兩個(gè)連接池.

配置映射器

MyBatis在Spring-Boot中的映射器一樣可以通過(guò)@Mapper掃描,但是對(duì)于不同的數(shù)據(jù)源的映射器要指定對(duì)應(yīng)的SqlSessionFactory.
因此需要配置兩個(gè)SqlSessionFactory

配置事務(wù)管理器

Spring中每個(gè)連接池又需要不同的事務(wù)去維護(hù).
因此需要配置兩個(gè)事務(wù)管理器

所以, 配置多個(gè)數(shù)據(jù)源主要是配置多個(gè)連接池, 每個(gè)連接池配置對(duì)應(yīng)的SqlSessionFactory和事務(wù)管理器.

示例代碼

@MapperScan(basePackages = "zxw.app.udpo.core.mapper.second", sqlSessionFactoryRef = SQLSESSION_FACTORY)
basePackages: 指定掃描的包,用于區(qū)分不同數(shù)據(jù)源下的Mapper. 不同數(shù)據(jù)源下的Mapper盡量放到不同的包下.
sqlSessionFactoryRef: 指定包下使用的SqlSessionFactory,即數(shù)據(jù)源

配置第一個(gè)數(shù)據(jù)源,事務(wù)管理器和SqlSessionFactory

package zxw.app.udpo.core.configure;

import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder;
import org.springframework.boot.context.properties.ConfigurationProperties;
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;

/**
 * @title: FDsConfigure
 * @description:
 * @author: zhangxw
 * @date: 2017/9/27 20:01
 * @params:
 * @returns
 */
@Configuration
@MapperScan(basePackages = "zxw.app.udpo.core.mapper.first")
public class FDsConfiguration {

    public static final String DATA_SOURCE = "fds";

    public static final String TRANSCATION_MANAGER = "ftm";

    public static final String SQLSESSION_FACTORY = "fsf";

    @Bean(name = DATA_SOURCE)
    @ConfigurationProperties(prefix = "datasource.first")
    @Primary
    public DataSource dataSource() {
        return DataSourceBuilder.create().build();
    }

    @Bean(name = TRANSCATION_MANAGER)
    @Primary
    public DataSourceTransactionManager dataSourceTransactionManager(@Qualifier(DATA_SOURCE) DataSource ds) {
        return new DataSourceTransactionManager(ds);
    }

    @Bean(name = SQLSESSION_FACTORY)
    @Primary
    public SqlSessionFactory sqlSessionFactory(@Qualifier(DATA_SOURCE) DataSource ds) throws Exception {
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        bean.setDataSource(ds);
        return bean.getObject();
    }


}

配置第二個(gè)數(shù)據(jù)源,事務(wù)管理器和SqlSessionFactory

package zxw.app.udpo.core.configure;

import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;

import javax.sql.DataSource;

import static zxw.app.udpo.core.configure.SDsConfiguration.SQLSESSION_FACTORY;

/**
 * @title: SDsConfiguration
 * @description:
 * @author: zhangxw
 * @date: 2017/9/27 20:15
 * @params:
 * @returns
 */
@Configuration
@MapperScan(basePackages = "zxw.app.udpo.core.mapper.second", sqlSessionFactoryRef = SQLSESSION_FACTORY)
public class SDsConfiguration {


    public static final String DATA_SOURCE = "sds";

    public static final String TRANSCATION_MANAGER = "stm";

    public static final String SQLSESSION_FACTORY = "ssf";

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

    @Bean(name = TRANSCATION_MANAGER)
    public DataSourceTransactionManager dataSourceTransactionManager(@Qualifier(DATA_SOURCE) DataSource ds) {
        return new DataSourceTransactionManager(ds);
    }

    @Bean(name = SQLSESSION_FACTORY)
    public SqlSessionFactory sqlSessionFactory(@Qualifier(DATA_SOURCE) DataSource ds) throws Exception {
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        bean.setDataSource(ds);
        return bean.getObject();
    }

}

不同數(shù)據(jù)源對(duì)應(yīng)的Mapper的使用

package zxw.app.udpo.core.mapper.first;

import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import zxw.app.udpo.core.entity.Dictionary;

/**
 * @title: DictionaryMapper
 * @description:
 * @author: zhangxw
 * @date: 2017/9/27 10:30
 * @params:
 * @returns
 */
@Mapper
public interface DictionaryMapper1 {

    @Select("select * from dictionary where code = #{code}")
    Dictionary findByCode(Integer code);

    @Select("select count(*) from dictionary")
    Integer count();


}
package zxw.app.udpo.core.mapper.second;

import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import zxw.app.udpo.core.entity.Dictionary;

/**
 * @title: DictionaryMapper
 * @description:
 * @author: zhangxw
 * @date: 2017/9/27 10:30
 * @params:
 * @returns
 */
@Mapper
public interface DictionaryMapper2 {

    @Select("select * from dictionary where code = #{code}")
    Dictionary findByCode(Integer code);

    @Select("select count(*) from dictionary")
    Integer count();
}

application.xml的配置

datasource:
  first:
    username: root
    password: root
    url: jdbc:mysql://192.168.56.101:3306/udpo?characterEncoding=utf8&useSSL=true
    driver-class-name: com.mysql.jdbc.Driver
    tomcat:
      max-active: 20
      max-idle: 10
      max-wait: 10000
      min-evictable-idle-time-millis: 60000
      min-idle: 3
      initial-size: 5
      validation-query: select 1 limit 1
      validation-interval: 30000
      validation-query-timeout: 20
      test-on-borrow: true
      test-on-connect: true
      test-on-return: true
      test-while-idle: true
      time-between-eviction-runs-millis: 5000
      remove-abandoned: true
      remove-abandoned-timeout: 300
      jdbc-interceptors: org.apache.tomcat.jdbc.pool.interceptor.ConnectionState;org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer;org.apache.tomcat.jdbc.pool.interceptor.ResetAbandonedTimer
      rollback-on-return: true
      commit-on-return: false
      alternate-username-allowed: false
      jmx-enabled: false
  second:
    username: root
    password: root
    url: jdbc:mysql://192.168.56.101:3306/udpo_b?characterEncoding=utf8&useSSL=true
    driver-class-name: com.mysql.jdbc.Driver
    tomcat:
      max-active: 20
      max-idle: 10
      max-wait: 10000
      min-evictable-idle-time-millis: 60000
      min-idle: 3
      initial-size: 5
      validation-query: select 1 limit 1
      validation-interval: 30000
      validation-query-timeout: 20
      test-on-borrow: true
      test-on-connect: true
      test-on-return: true
      test-while-idle: true
      time-between-eviction-runs-millis: 5000
      remove-abandoned: true
      remove-abandoned-timeout: 300
      jdbc-interceptors: org.apache.tomcat.jdbc.pool.interceptor.ConnectionState;org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer;org.apache.tomcat.jdbc.pool.interceptor.ResetAbandonedTimer
      rollback-on-return: true
      commit-on-return: false
      alternate-username-allowed: false
      jmx-enabled: false

注意

添加@EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class}), 如下:

package zxw.app.udpo.core;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.context.annotation.ComponentScan;

/**
 * Hello world!
 *
 */
@SpringBootApplication
//  Don't forget exclude datasource auto configuration on start class:
@EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class})
@ComponentScan(basePackages = "zxw.app.udpo.core")
public class App
{
    public static void main( String[] args )
    {
        SpringApplication.run(App.class, args);
    }
}

如果有問題,歡迎留言,一起探討

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容