springboot + druid + mybatis plus multiple data source configuration

Thinking

  1. yml the plurality of data source information
  2. By switching different data sources AOP
  3. With mybatis plus use

POM dependence

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter</artifactId>
</dependency>
<!-- AOP依赖 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>2.0.0</version>
</dependency>
<!-- MyBatisPlus -->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.1.0</version>
</dependency>
<!--Mysql-->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.6</version>
    <scope>runtime</scope>
</dependency>
<!-- Druid依赖 -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid-spring-boot-starter</artifactId>
    <version>1.1.10</version>
</dependency>

 

YML Configuration

spring:
  aop:
    proxy-target-class: true
    auto: true
  datasource:
    druid:
      es:
        url: jdbc:mysql://192.168.21.181:3306/jarvis
        username: root
        password: 123456
        type: com.alibaba.druid.pool.DruidDataSource
        driver-class-name: com.mysql.jdbc.Driver
        initialSize: 5
        minIdle: 5
        maxActive: 20
      wx:
        initialSize: 5
        minIdle: 5
        maxActive: 20
        type: com.alibaba.druid.pool.DruidDataSource
        driver-class-name: com.mysql.jdbc.Driver
        username: root
        password: 123456
        url: jdbc:mysql://192.168.21.181:3306/jarvis_wx

A plurality of data sources boot loader

package com.jarvis.config;

import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
import com.baomidou.mybatisplus.core.MybatisConfiguration;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import com.baomidou.mybatisplus.extension.plugins.PerformanceInterceptor;
import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.type.JdbcType;
import org.mybatis.spring.annotation.MapperScan;
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.context.annotation.Primary;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;

@Configuration
@EnableTransactionManagement
@MapperScan("com.jarvis.task.*.mapper")
public class MybatisPlusConfig { 

    / ** * 
     * PLUS performance optimization 
     * / 
    @Bean 
    public PerformanceInterceptor performanceInterceptor () { 
        PerformanceInterceptor performanceInterceptor = new new PerformanceInterceptor ();
         / * <- analysis of the SQL execution performance, development environment, the line is not recommended!. maxTime refers to the maximum length is performed SQL -> * / 
        // performanceInterceptor.setMaxTime (1000); 
        / * <- if the SQL format default to false ->! * / 
        performanceInterceptor.setFormat ( to false );
         return performanceInterceptor; 
    } 

    / ** 
     * the mybatis pagination plug-PLUS 
     * /
    @Bean
    public PaginationInterceptor paginationInterceptor() {
        PaginationInterceptor page = new PaginationInterceptor();
        page.setDialectType("mysql");
        return page;
    }


    @Bean(name = "esDb")
    @ConfigurationProperties(prefix = "spring.datasource.druid.es" )
    public DataSource esDb () {
        return DruidDataSourceBuilder.create().build();
    }

    @Bean(name = "wxDb")
    @ConfigurationProperties(prefix = "spring.datasource.druid.wx" )
    public DataSource wxDb () {
        return DruidDataSourceBuilder.create().build();
    }
    /**
     * 动态数据源配置
     * @return
     */
    @Bean
    @Primary
    public DataSource multipleDataSource (@Qualifier("esDb") DataSource esDb,
                                          @Qualifier("wxDb") DataSource wxDb ) {
        DynamicDataSource dynamicDataSource = new DynamicDataSource();
        Map< Object, Object > targetDataSources = new HashMap<>(2);
        targetDataSources.put(DBTypeEnum.ES.getValue(), esDb );
        targetDataSources.put(DBTypeEnum.WX.getValue(), wxDb);
        dynamicDataSource.setTargetDataSources(targetDataSources);
        dynamicDataSource.setDefaultTargetDataSource(esDb);
        return dynamicDataSource;
    }

    @Bean("sqlSessionFactory")
    public SqlSessionFactory sqlSessionFactory() throws Exception {
        MybatisSqlSessionFactoryBean sqlSessionFactory = new MybatisSqlSessionFactoryBean();
        sqlSessionFactory.setDataSource(multipleDataSource(esDb(),wxDb()));
        //sqlSessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:/mapper/*/*Mapper.xml"));

        MybatisConfiguration configuration = new MybatisConfiguration();
        //configuration.setDefaultScriptingLanguage(MybatisXMLLanguageDriver.class);
        configuration.setJdbcTypeForNull(JdbcType.NULL);
        configuration.setMapUnderscoreToCamelCase(true);
        configuration.setCacheEnabled(false);
        sqlSessionFactory.setConfiguration(configuration);
        sqlSessionFactory.setPlugins(new Interceptor[]{ //PerformanceInterceptor(),OptimisticLockerInterceptor()
                paginationInterceptor() //添加分页功能
        });
//        sqlSessionFactory.setGlobalConfig(globalConfiguration());
        return sqlSessionFactory.getObject();
    }

//    @Bean
//    public GlobalConfiguration globalConfiguration() {
//        GlobalConfiguration conf = new GlobalConfiguration(new LogicSqlInjector());
//        conf.setLogicDeleteValue("-1");
//        conf.setLogicNotDeleteValue("1");
//        conf.setIdType(0);
//        conf.setMetaObjectHandler(new MyMetaObjectHandler());
//        conf.setDbColumnUnderline(true);
//        conf.setRefresh(true);
//        return conf;
//    }
}

DBType enumeration class

public enum DBTypeEnum {
    ES("es"), WX("wx");
    private String value;

    DBTypeEnum(String value) {
        this.value = value;
    }

    public String getValue() {
        return value;
    }
}

Dynamic data sources decisions

Import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource; 

public  class DynamicDataSource the extends AbstractRoutingDataSource {
     / ** 
     * Get current data source which 
     * @return 
     * / 
    @Override 
    protected Object determineCurrentLookupKey () {
         return DbContextHolder.getDbType (); 
    } 
}

Setting, get data source

public  class DbContextHolder {
     Private  static  Final the ThreadLocal ContextHolder = new new the ThreadLocal <> ();
     / ** 
     * Set Data Source 
     * @param dbTypeEnum
      * / 
    public  static  void setDbType (DBTypeEnum dbTypeEnum) { 
        contextHolder.set (dbTypeEnum.getValue ()); 
    } 

    / ** 
     * Get the current data source 
     * @return 
     * / 
    public  static String getDbType () {
         return (String) contextHolder.get (); 
    } 

    / ** 
     * Clear context data
     */
    public static void clearDbType() {
        contextHolder.remove();
    }
}

AOP implemented data source switching

Import lombok.extern.slf4j.Slf4j;
 Import org.aspectj.lang.annotation *. ;
 Import org.springframework.core.annotation.Order;
 Import org.springframework.stereotype.Component; 

@Component 
@Aspect 
the @Order ( -100) // this is to ensure AOP annotations take effect before the transaction, the smaller the value of the order, the higher the priority 
@ SLF4J
 public  class DataSourceSwitchAspect { 

    @Pointcut ( "Execution (* com.jarvis.task.db2es.mapper .. *. * (..)) " )
     Private  void jarvisAspect () { 
    } 

    @Pointcut ( " Execution (com.jarvis.task.dt2db.mapper .. * *. * (..)) " )
     Private void jarvisWxAspect () { 
    } 

    @Before ( "jarvisAspect ()" )
     public  void jarvisDb () { 
        log.info ( "switch to the ES data source ..." ); 
        DbContextHolder.setDbType (DBTypeEnum.ES); 
    } 

    @Before ( "jarvisWxAspect ()" )
     public  void jarvisWxDb () { 
        log.info ( "WX switch to the data source ..." ); 
        DbContextHolder.setDbType (DBTypeEnum.WX); 
    } 
}

layer structure mapper

 reference

  https://www.jianshu.com/p/ff5af6c59365?utm_source=oschina-app

Guess you like

Origin www.cnblogs.com/szwdun/p/11263201.html