天天看點

Spring Boot+mybatis 建立多資料源連接配接                  Spring Boot+mybatis 建立多資料源連接配接

                  Spring Boot+mybatis 建立多資料源連接配接

一、背景:公司系統需要做異構資料庫資料遷移,需要配置多資料源,配置過程中也出現過些小問題,是以在此做下記錄;

二、代碼位址:https://github.com/tiedungao/multipleDataSource.git

三、代碼講解

1、項目結構:

Spring Boot+mybatis 建立多資料源連接配接                  Spring Boot+mybatis 建立多資料源連接配接

2、主要配置檔案:首先配置檔案 application.yml

server:
  port: 8086
  servlet:
    context-path: /
#http
http:
  encoding:
    charset: UTF-8
jackson:
  date-format: yyyy-MM-dd HH:mm:ss
  time-zone: GMT+8
  default-property-inclusion: non_null

spring:
  profiles:
    active: local
  http:
    encoding:
      charset: UTF-8
  datasource:
    #druid
    initialSize: 1  #初始化大小
    minIdle: 1      #最小
    maxActive: 300  #最大
    maxWait: 60000  #最大等待時長,機關(毫秒)
    #timeBetweenEvictionRunsMillis: 300000L #間隔多久進行一次檢測,檢測需要關閉的空閑連接配接(機關:毫秒)
    minEvictableIdleTimeMillis: 300000 #一個連接配接在連接配接池中的最小生存時間(機關:毫秒)
    validationQuery: SELECT 1 FROM DUAL
    testWhileIdle: true
    testOnBorrow: false
    testOnReturn: false
    #打開PSCache,并且指定每個連接配接上的PSCache的大小
    poolPreparedStatements: true
    maxOpenPreparedStatements: 20
    #監控統計攔截的filters,去掉後監控界面sql無法統計,wall用于防火牆
    filters: log4j
    #通過connectionProperties屬性打開mergeSQL功能,慢SQL記錄
    connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
    #合并多個DruidDataSource的監控資料
    useGlobalDataSourceStat: true

mybatis:
  old:
    mapper-locations: classpath:/mapper/old/*.xml
    type-aliases-package: com.shallbuy.transfer.entity
    configuration:
      cache-enabled: true
      lazy-loading-enabled: true
      use-column-label: true
      use-generated-keys: true
      default-statement-timeout: 25000
      log-prefix: mybatis
  new:
    mapper-locations: classpath:/mapper/newer/*.xml
    type-aliases-package: com.shallbuy.transfer.entity
    configuration:
      cache-enabled: true
      lazy-loading-enabled: true
      use-column-label: true
      use-generated-keys: true
      default-statement-timeout: 25000
      log-prefix: mybatis
           

然後是引用的application-local.yml

spring:
  datasource:
    druid:
      old:
        type: com.alibaba.druid.pool.DruidDataSource
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: *************************
        username: ****************
        password: ****************** 
        initial-size: 8
        min-idle: 3
        max-active: 300
        max-wait: 60000
        min-evictable-idle-time-millis: 300000
        validation-query: SELECT 1 FROM DUAL
        test-while-idle: true
        test-on-borrow: false
        test-on-return: false
        pool-prepared-statements: false
        max-open-prepared-statements: -1
        connection-properties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
        use-global-data-source-stat: false
      new:
        type: com.alibaba.druid.pool.DruidDataSource
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: *****************
        username: ************
        password: **************
        initial-size: 8
        min-idle: 5
        max-active: 300
        max-wait: 60000
        min-evictable-idle-time-millis: 300000
        validation-query: SELECT 1 FROM DUAL
        test-while-idle: true
        test-on-borrow: false
        test-on-return: false
        pool-prepared-statements: false
        max-open-prepared-statements: -1
        connection-properties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
        use-global-data-source-stat: false
           

參數可以根據自己的系統和業務進行修改

4、然後是配置類:DruidDataSourceNewConfig.java(新資料源配置類)

package com.shallbuy.transfer.config;

import com.alibaba.druid.pool.DruidDataSource;
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 org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import javax.sql.DataSource;

/**
 * @author gtd
 * description:
 * date: Create in 9:31 2019/4/13
 */
@Configuration
@EnableTransactionManagement
public class DruidDataSourceNewConfig {

    /**
     * 資料源配置
     * @return
     */
    @Bean("newDataSource")
    @Primary
    @ConfigurationProperties(prefix = "spring.datasource.druid.new")
    public DataSource dataSource() {
        return new DruidDataSource();
    }

    /**
     * 事務管理
     * @return
     */
    @Bean("newTransactionManager")
    public PlatformTransactionManager transactionManager() {
        DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager();
        dataSourceTransactionManager.setDataSource(this.dataSource());
        return dataSourceTransactionManager;
    }

}
           

老資料源配置類:DruidDataSourceOldConfig.java 和新資料源配置類似

package com.shallbuy.transfer.config;

import com.alibaba.druid.pool.DruidDataSource;
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 org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import javax.sql.DataSource;
import java.sql.SQLException;

/**
 * @author gtd
 * description:
 * date: Create in 9:31 2019/4/13
 */
@Configuration
@EnableTransactionManagement
public class DruidDataSourceOldConfig {

    @Bean("oldDataSource")
    @Primary
    @ConfigurationProperties(prefix = "spring.datasource.druid.old")
    public DataSource dataSource() {
        return  new DruidDataSource();
    }

    @Bean("oldTransactionManager")
    public PlatformTransactionManager transactionManager() {
        DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager();
        dataSourceTransactionManager.setDataSource(this.dataSource());
        return dataSourceTransactionManager;
    }

}
           

mybatis配置類:MybatisNewDataSourceConfig.java 新資料源對應的mybatis配置類

package com.shallbuy.transfer.config;

import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import javax.sql.DataSource;
import java.io.IOException;

/**
 * @author gtd
 * description:
 * date: Create in 21:36 2019/4/15
 */
@Configuration
@ConfigurationProperties(prefix = "mybatis.new")
@MapperScan(basePackages = {"com.shallbuy.transfer.dao.newer"}, sqlSessionFactoryRef = "newSqlSessionFactory")
public class MybatisNewDataSourceConfig {
    private static final Logger logger = LoggerFactory.getLogger(MybatisNewDataSourceConfig.class);

    @Resource
    @Qualifier("newDataSource")
    private DataSource newDataSource;

    //類型别名
    private String typeAliasesPackage;
    //掃描Mapper位址
    private String mapperLocations;

    public String getTypeAliasesPackage() {
        return typeAliasesPackage;
    }

    public void setTypeAliasesPackage(String typeAliasesPackage) {
        this.typeAliasesPackage = typeAliasesPackage;
    }

    public String getMapperLocations() {
        return mapperLocations;
    }

    public void setMapperLocations(String mapperLocations) {
        this.mapperLocations = mapperLocations;
    }

    @Bean(name="newSqlSessionFactory")
    public SqlSessionFactory newSqlSessionFactoryBean(){
        logger.info("------初始化newSqlSessionFactory------");
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        SqlSessionFactory sqlSessionFactory = null;
        bean.setDataSource(newDataSource);
        try {
            org.springframework.core.io.Resource[] resources = new PathMatchingResourcePatternResolver()
                    .getResources(mapperLocations);
            bean.setMapperLocations(resources);
            bean.setTypeAliasesPackage(typeAliasesPackage);
            sqlSessionFactory = bean.getObject();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return sqlSessionFactory;
    }

}
           

老資料源的mybatis配置類:MybatisOldDataSourceConfig.java

package com.shallbuy.transfer.config;

import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;

import javax.annotation.Resource;
import javax.sql.DataSource;

/**
 * @author gtd
 * description:
 * date: Create in 21:36 2019/4/15
 */
@Configuration
@ConfigurationProperties(prefix = "mybatis.old")
@MapperScan(basePackages = {"com.shallbuy.transfer.dao.old"}, sqlSessionFactoryRef = "oldSqlSessionFactory")
public class MybatisOldDataSourceConfig {
    private static final Logger logger = LoggerFactory.getLogger(MybatisOldDataSourceConfig.class);

    @Resource
    @Qualifier("oldDataSource")
    private DataSource oldDataSource;
    //類型别名
    private String typeAliasesPackage;
    //掃描Mapper位址
    private String mapperLocations;

    public String getTypeAliasesPackage() {
        return typeAliasesPackage;
    }

    public void setTypeAliasesPackage(String typeAliasesPackage) {
        this.typeAliasesPackage = typeAliasesPackage;
    }

    public String getMapperLocations() {
        return mapperLocations;
    }

    public void setMapperLocations(String mapperLocations) {
        this.mapperLocations = mapperLocations;
    }

    @Bean(name="oldSqlSessionFactory")
    public SqlSessionFactory oldSqlSessionFactoryBean(){
        logger.info("------初始化oldSqlSessionFactory------");
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        SqlSessionFactory sqlSessionFactory = null;
        bean.setDataSource(oldDataSource);
        try {
            org.springframework.core.io.Resource[] resources = new PathMatchingResourcePatternResolver()
                    .getResources(mapperLocations);
            bean.setMapperLocations(resources);
            bean.setTypeAliasesPackage(typeAliasesPackage);
            sqlSessionFactory = bean.getObject();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return sqlSessionFactory;
    }

}
           

5、除了上面配置,在啟動類上注解上需要修改為@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})

6、其他配置和普通Spring Boot項目相同,然後通過掃描不同目錄下的mapper檔案,使用不同的資料源。

繼續閱讀