spring boot 中 Mybatis plus 多數據源的配置方法

最近在學習spring boot,發如今jar包依賴方面作不多的工做量就能夠了,對於數據庫操做,我用的比較多的是mybatis plus,在中央倉庫已經有mybatis-plus的插件了,對於單數據源來講直接使用就是了,但我本身的項目常常會有多數據源的狀況,本身去試着寫數據源的代碼,核心的方法參考mp說明文檔中多數據源的處理,使用動態數據源,根據需求去切換數據源java

新建spring-boot項目

這一步你們去參考其它教程,很簡單mysql

定義數據源相關Model

動態數據源

繼承了抽像的數據源,並實現了DataSource,歸根結底仍是數據就是了,在這裏面進行擴展,實現determiniCurrentlookupKey,也就是獲取當前須要使用數據源的key值,在父類方法中有一個map,用來保存key值與數據源的對應關係,而key值是與當前線程相關的,DbcontextHolder代碼見下spring

  1. package com.zhangshuo.common.dataSource;
    import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
    /**
    * Created by Administrator on 2017/5/31 0031.
    */
    publicclassDynamicDataSourceextendsAbstractRoutingDataSource{
    /**
    * 取得當前使用哪一個數據源
    *
    * @return
    */
    @Override
    protectedObject determineCurrentLookupKey(){
    returnDbContextHolder.getDbType();
    }
    }

     

定義DbContextHolder

裏面包含靜態方法,用來設置或獲取線程相關的數據源別名sql

  1. publicclassDbContextHolder{
    privatestaticfinalThreadLocal<String> contextHolder =newThreadLocal<>();
    /**
    * 設置數據源
    *
    * @param dbTypeEnum
    */
    publicstaticvoid setDbType(DBTypeEnum dbTypeEnum){
    contextHolder.set(dbTypeEnum.getValue());
    }
    /**
    * 取得當前數據源
    *
    * @return
    */
    publicstaticString getDbType(){
    return contextHolder.get();
    }
    /**
    * 清除上下文數據
    */
    publicstaticvoid clearDbType(){
    contextHolder.remove();
    }
    }

     

定義數據源枚舉類

簡化設置線程相關數據源名稱的記憶壓力;直接從全部的數據源的枚舉中去選就能夠了~數據庫

  1. publicenumDBTypeEnum{
    datasource1("datasource1"), datasource2("datasource2");
    privateString value;
    DBTypeEnum(String value){
    this.value = value;
    }
    publicString getValue(){
    return value;
    }
    }

     

生成 dataource 對象及 mp須要的對象

resources/application.properties的配置

在這裏定義的屬性名要與DruidDataSource和 SqlSessionFactory中須要的屬性相同,使用ConfigurationProperties註解來減小代碼apache

  1. datasource1:
      username: root
      password: 123456
      filters: mergeStat,wall,logback
      initialSize: 5
      maxActive: 50
      minIdle: 5
      maxWait: 6000
      validationQuery: SELECT 'x'
      testOnBorrow: true
      testOnReturn: true
      testWhileIdle: true
      timeBetweenEvictionRunsMillis: 60000
      minEvictableIdleTimeMillis: 300000
      removeAbandoned: true
      removeAbandonedTimeout: 1800
      logAbandoned: true
      url: jdbc:mysql://192.168.168.118:3306/test?useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&transformedBitIsBoolean=true&useSSL=false
    
    
    
    mybatis-plus1:
    # 數據源名稱
      datasource: datasource1
      # mapper配置路徑
      mapperLocations:
        classpath:/mapper/test1/*.xml
      # mybatis配置路徑
      configLocation: classpath:/mybatis-config.xml
      # entity的包
      typeAliasesPackage: com.zhangshuo/test1/entity
      # 全局配置
      globalConfiguration:
        # id生成策略 0 自增 1 用戶輸入
        idType: 0
        # 靈據數類型
        dbType: mysql
        # 字段是否爲下劃線格式
        dbColumnUnderline: false
    
    datasource2:
      username: root
      password: 123456
      filters: mergeStat,wall,logback
      initialSize: 5
      maxActive: 50
      minIdle: 5
      maxWait: 6000
      validationQuery: SELECT 'x'
      testOnBorrow: true
      testOnReturn: true
      testWhileIdle: true
      timeBetweenEvictionRunsMillis: 60000
      minEvictableIdleTimeMillis: 300000
      removeAbandoned: true
      removeAbandonedTimeout: 1800
      logAbandoned: true
      url: jdbc:mysql://192.168.168.118:3306/sms?useUnicode=true&characterEncoding=utf-8
    
    mybatis-plus2:
    # 數據源名稱
      datasource: datasource2
      # mapper配置路徑
      mapperLocations:
        classpath:/mapper/test2/*.xml
      # mybatis配置路徑
      configLocation:
      # entity的包
      typeAliasesPackage: com.zhangshuo/test2/entity
      # 全局配置
      globalConfiguration:
        # id生成策略 0 自增 1 用戶輸入
        idType: 0
        # 靈據數類型
        dbType: mysql
        # 字段是否爲下劃線格式
        dbColumnUnderline: false

     

生成相應對象

  1. import com.alibaba.druid.pool.DruidDataSource;
    import com.baomidou.mybatisplus.spring.MybatisSqlSessionFactoryBean;
    import com.zhangshuo.common.dataSource.DynamicDataSource;
    import org.mybatis.spring.annotation.MapperScan;
    import org.springframework.beans.factory.annotation.Qualifier;
    import org.springframework.boot.context.properties.ConfigurationProperties;
    import org.springframework.boot.context.properties.ConfigurationPropertiesBinding;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.Primary;
    import javax.sql.DataSource;
    import java.util.Map;
    import java.sql.SQLException;
    import java.util.HashMap;
    /**
    * Created by Administrator on 2017/5/31 0031.
    */
    @Configuration
    @MapperScan(value ={"com.zhangshuo.test1.mapper","com.zhangshuo.test2.mapper"})
    publicclassDataSourceConfig{
    @ConfigurationProperties(prefix ="datasource1")
    @Bean(name ="datasource1")
    // @Primary
    /**
    * 在方法上註解configurationProperties時,將會把屬性注入到返回結果的bean中
    */
    publicDruidDataSource dataSource1()throwsSQLException{
    returnnewDruidDataSource();
    }
    @ConfigurationProperties(prefix ="datasource2")
    @Bean(name ="datasource2")
    /**
    * 在方法上註解configurationProperties時,將會把屬性注入到返回結果的bean中
    */
    publicDruidDataSource dataSource2()throwsSQLException{
    returnnewDruidDataSource();
    }
    @Bean(name ="datasource")
    @Primary
    publicDynamicDataSource dynamicDataSource(@Qualifier(value ="datasource1")DataSource dataSource1,@Qualifier(value ="datasource2")DataSource dataSource2){
    DynamicDataSource bean =newDynamicDataSource();
    Map<Object,Object> targetDataSources =newHashMap<>();
    targetDataSources.put("datasource1",dataSource1);
    targetDataSources.put("datasource2", dataSource2);
    bean.setTargetDataSources(targetDataSources);
    bean.setDefaultTargetDataSource(dataSource1);
    return bean;
    }
    @Bean(name ="sessionFactory1")
    @ConfigurationProperties(prefix ="mybatis-plus1")
    @ConfigurationPropertiesBinding()
    @Primary
    publicMybatisSqlSessionFactoryBean sqlSessionFactory1(@Qualifier(value ="datasource")DataSource dataSource){
    MybatisSqlSessionFactoryBean bean =newMybatisSqlSessionFactoryBean();
    bean.setDataSource(dataSource);
    return bean;
    }
    @Bean(name ="sessionFactory2")
    @ConfigurationProperties(prefix ="mybatis-plus2")
    @ConfigurationPropertiesBinding()
    publicMybatisSqlSessionFactoryBean sqlSessionFactory2(@Qualifier(value ="datasource")DataSource dataSource){
    MybatisSqlSessionFactoryBean bean =newMybatisSqlSessionFactoryBean();
    bean.setDataSource(dataSource);
    return bean;
    }
    }

     

設置AOP用來自動切換數據源

在這裏說明下個人目錄結構:
com.zhangshuo.test1.controller/service/mapper
com.zhangshuo.test2.controller/service/mappersession

設置AOP

在dao層進行切換mybatis

  1. import com.zhangshuo.common.dataSource.DBTypeEnum;
    import com.zhangshuo.common.dataSource.DbContextHolder;
    import org.aspectj.lang.annotation.Aspect;
    import org.aspectj.lang.annotation.Before;
    import org.aspectj.lang.annotation.Pointcut;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.stereotype.Component;
    /**
    * Created by Administrator on 2017/5/31 0031.
    * 以dao層進行切換
    */
    @Component
    @Aspect
    publicclassDataSourceInterceptor{
    Logger logger =LoggerFactory.getLogger(DataSourceInterceptor.class);
    @Pointcut(value ="execution(public * com.zhangshuo.test1.mapper.**.*(..))")
    privatevoid datasource1ServicePointcut(){};
    @Pointcut(value ="execution(public * com.zhangshuo.test2.mapper.**.*(..))")
    privatevoid datasource2ServicePointcut(){};
    /**
    * 切換數據源1
    */
    @Before("datasource1ServicePointcut()")
    publicvoid dataSource1Interceptor(){
    logger.debug("切換到數據源{}..............................","datasource1");
    DbContextHolder.setDbType(DBTypeEnum.datasource1);
    }
    /**
    * 切換數據源2
    */
    @Before("datasource2ServicePointcut()")
    publicvoid dataSource2Interceptor(){
    logger.debug("切換到數據源{}.......................","datasource2");
    DbContextHolder.setDbType(DBTypeEnum.datasource2);
    }
    }

     

到這裏就能夠進行測試了;
順帶貼下mybatis-plus的分頁插件,我是定義到了mybatis-config.xml中,也能夠手動在sqlSessionfacotry中的setPlugins中()定義;app

  1. <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE configuration
            PUBLIC "-//ibatis.apache.org//DTD Config 3.0//EN"
            "http://ibatis.apache.org/dtd/ibatis-3-config.dtd">
    
    <configuration>
        <settings>
            <setting name="cacheEnabled" value="false"/>
            <setting name="lazyLoadingEnabled" value="false"/>
            <setting name="aggressiveLazyLoading" value="true"/>
            <setting name="logImpl" value="slf4j"/>
        </settings>
        <plugins>
            <plugin interceptor="com.baomidou.mybatisplus.plugins.PaginationInterceptor">
                <property name="dialectType" value="mysql" />
                <property name="optimizeType" value="aliDruid" />
            </plugin>
        </plugins>
    </configuration>
相關文章
相關標籤/搜索