Spirngboot 2.X 整合mybatis-plus +druid 多数据源的实现

首先加入依赖:

        <!-- AOP-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>

        <!--MySQL 连接驱动依赖-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>

        <!--mybatis-plus数据持久层-->
        <!-- https://mvnrepository.com/artifact/com.baomidou/mybatis-plus -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus</artifactId>
            <version>3.3.1</version>
        </dependency>
  <!-- https://mvnrepository.com/artifact/org.mybatis.spring.boot/mybatis-spring-boot-starter -->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.1.2</version>
        </dependency>
  <!--druid数据连接池-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.1.22</version>
        </dependency>
 <!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>5.2.6.RELEASE</version>
        </dependency>

在配置文件增加下面配置:

spring:
  jackson:
    time-zone: GMT+8
    date-format: yyyy-MM-dd HH:mm:ss
  aop:
    auto: true
    proxy-target-class: true
  datasource:
    druid:
      db1:
        url: jdbc:mysql://ip:端口/db1?useSSL=false&characterEncoding=UTF-8&autoReconnect=true&zeroDateTimeBehavior=convertToNull&useUnicode=true&rewriteBatchedStatements=true
        username: ****#mysql账号
        password: ***#mysql密码
        driver-class-name: com.mysql.cj.jdbc.Driver
        initialSize: 5
        minIdle: 5
        maxActive: 20
      db2:
        url: jdbc:mysql://****/db2?useSSL=false&characterEncoding=UTF-8&autoReconnect=true&zeroDateTimeBehavior=convertToNull&useUnicode=true&rewriteBatchedStatements=true
        username: ****#mysql账号
        password: ***#mysql密码
        driver-class-name: com.mysql.cj.jdbc.Driver
        initialSize: 5
        minIdle: 5
        maxActive: 20


mybatis:
  type-aliases-package: com.*.*.entity #实体映射类包的位置
  configuration:
    # 驼峰下划线转换
    map-underscore-to-camel-case: true
  mapper-locations: classpath*:/mapper/**/*.xml

#设置druid后台访问白名单
druid:
  config:
    white-list: 127.0.0.1,loclhost

下面配置DruidConfig

import com.alibaba.druid.support.http.StatViewServlet;
import com.alibaba.druid.support.http.WebStatFilter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.List;

@Configuration
public class DruidConfig {

  @Value("#{'${druid.config.white-list}'.split(',')}")
  private List<String> whitelist;
  /**
   * 注册ServletRegistrationBean
   *
   * @return
   */
  @Bean
  public ServletRegistrationBean druidServlet() {
    ServletRegistrationBean reg = new ServletRegistrationBean(new StatViewServlet(), "/druid/*");
    // IP白名单
    for (String ip : whitelist) {
      reg.addInitParameter("allow", ip);
    }
    // IP黑名单(共同存在时,deny优先于allow)
    //        reg.addInitParameter("deny","127.0.0.1");
    // 控制台管理用户
    reg.addInitParameter("loginUsername", "**");//设置登陆账号
    reg.addInitParameter("loginPassword", "***");//设置登陆密码
    // 是否能够重置数据
    reg.addInitParameter("resetEnable", "false");
    return reg;
  }

  /**
   * 注册FilterRegistrationBean
   *
   * @return
   */
  @Bean
  public FilterRegistrationBean filterRegistrationBean() {
    FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
    filterRegistrationBean.setFilter(new WebStatFilter());
    filterRegistrationBean.addUrlPatterns("/*");
    filterRegistrationBean.addInitParameter(
        "exclusions", "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*");
    filterRegistrationBean.addInitParameter("profileEnable", "true");
    filterRegistrationBean.addInitParameter("principalCookieName", "USER_COOKIE");
    filterRegistrationBean.addInitParameter("principalSessionName", "USER_SESSION");
    filterRegistrationBean.addInitParameter("DruidWebStatFilter", "/*");
    return filterRegistrationBean;
  }
}

定义数据源枚举

public enum DBTYPE {
    db1("db1"),
    db2("db2"),
    db3("db3");

    private String value;

    private DBTYPE(String value) {
        this.value = value;
    }

    public String getValue() {
        return this.value;
    }
}

定义数据源上下文



public class DbContextHolder {
    private static final ThreadLocal contextHolder = new ThreadLocal();

    public DbContextHolder() {
    }

    public static void setDbType(DBTYPE dbTypeEnum) {
        contextHolder.set(dbTypeEnum.getValue());
    }

    public static String getDbType() {
        return (String)contextHolder.get();
    }

    public static void clearDbType() {
        contextHolder.remove();
    }
}

动态数据源设置

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

/**
 * @program: common
 * @description: 动态数据源
 * @author: linwl
 * @create: 2020-06-20 15:33
 **/
public class DynamicDataSource extends AbstractRoutingDataSource {

    @Override
    public Object determineCurrentLookupKey()
    {
        return DbContextHolder.getDbType();
    }
}

定义动态数据源切换类

import db.DBTYPE;
import db.DbContextHolder;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

@Component
@Order(value = -100)
@Slf4j
@Aspect
public class DataSourceSwitchAspect {
  //数据源1切点
  @Pointcut("execution(* com.*.mapper.db1..*.*(..))")
  public void db1Aspect() {}
  //数据源2切点
  @Pointcut("execution(* com.*.mapper.db2..*.*(..))")
  public void db2Aspect() {}
  //数据源3切点
  @Pointcut("execution(* com.*.mapper.db3..*.*(..))")
  public void db3Aspect() {}

  @Before("db1Aspect()")
  public void getdb1() {
    log.info("切换到db1 数据源...");
    DbContextHolder.setDbType(DBTYPE.db1);
  }

  @Before("db2Aspect()")
  public void getdb2() {
    log.info("切换到db2 数据源...");
    DbContextHolder.setDbType(DBTYPE.db2);
  }

  @Before("db3Aspect()")
  public void getdb3() {
    log.info("切换到db3 数据源...");
    DbContextHolder.setDbType(DBTYPE.db3);
  }

  @After("db1Aspect()")
  public void romvedb1() {
    log.info("移除数据源");
    DbContextHolder.clearDbType();
  }

  @After("db2Aspect()")
  public void romvedb2() {
    log.info("移除数据源");
    DbContextHolder.clearDbType();
  }

  @After("db3Aspect()")
  public void romvedb3() {
    log.info("移除数据源");
    DbContextHolder.clearDbType();
  }
}

前期的配置基本完成了,接下来就是要进入MybatisPlus的配置了
配置如下:

import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.core.MybatisConfiguration;
import com.baomidou.mybatisplus.core.MybatisXMLLanguageDriver;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;
import db.DBTYPE;
import db.DynamicDataSource;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.mapping.DatabaseIdProvider;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.annotation.MapperScan;
import org.mybatis.spring.boot.autoconfigure.MybatisProperties;
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.context.annotation.Primary;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.ResourceLoader;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.util.StringUtils;

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

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

  @Autowired private MybatisProperties properties;

  private ResourceLoader resourceLoader = new DefaultResourceLoader();

  @Autowired(required = false)
  private DatabaseIdProvider databaseIdProvider;

  /**
   * mybatis-plus分页插件
* 文档:http://mp.baomidou.com
*/
@Bean public PaginationInterceptor paginationInterceptor() { PaginationInterceptor page = new PaginationInterceptor(); page.setDbType(DbType.MYSQL); return new PaginationInterceptor(); } @Bean(name = "db1") @ConfigurationProperties(prefix = "spring.datasource.druid.db1") public DataSource db1() { return DruidDataSourceBuilder.create().build(); } @Bean(name = "db2") @ConfigurationProperties(prefix = "spring.datasource.druid.db2") public DataSource db2() { return DruidDataSourceBuilder.create().build(); } // @Bean(name = "db3") // @ConfigurationProperties(prefix = "spring.datasource.druid.db3") // public DataSource db3() { // return DruidDataSourceBuilder.create().build(); // } /** * 动态数据源配置 * * @return */ @Bean @Primary public DataSource multipleDataSource( @Qualifier("db1") DataSource db1, @Qualifier("db2") DataSource db2) { DynamicDataSource dynamicDataSource = new DynamicDataSource(); Map<Object, Object> targetDataSources = new HashMap<>(3); targetDataSources.put(DBTYPE.db1.getValue(), db1); targetDataSources.put(DBTYPE.db2.getValue(), db2); dynamicDataSource.setTargetDataSources(targetDataSources); dynamicDataSource.setDefaultTargetDataSource(db1); return dynamicDataSource; } @Bean("sqlSessionFactory") public SqlSessionFactory sqlSessionFactory() throws Exception { try { MybatisSqlSessionFactoryBean mybatisPlus = new MybatisSqlSessionFactoryBean(); mybatisPlus.setDataSource(multipleDataSource(db1(), db2())); if (StringUtils.hasText(this.properties.getConfigLocation())) { mybatisPlus.setConfigLocation( this.resourceLoader.getResource(this.properties.getConfigLocation())); } mybatisPlus.setPlugins(paginationInterceptor()); MybatisConfiguration mc = new MybatisConfiguration(); mc.setDefaultScriptingLanguage(MybatisXMLLanguageDriver.class); mybatisPlus.setConfiguration(mc); if (this.databaseIdProvider != null) { mybatisPlus.setDatabaseIdProvider(this.databaseIdProvider); } if (StringUtils.hasLength(this.properties.getTypeAliasesPackage())) { mybatisPlus.setTypeAliasesPackage(this.properties.getTypeAliasesPackage()); } if (StringUtils.hasLength(this.properties.getTypeHandlersPackage())) { mybatisPlus.setTypeHandlersPackage(this.properties.getTypeHandlersPackage()); } if (!ObjectUtils.isEmpty(this.properties.resolveMapperLocations())) { mybatisPlus.setMapperLocations(this.properties.resolveMapperLocations()); } return mybatisPlus.getObject(); } catch (Exception e) { log.error(MessageFormat.format("初始化Mybatis配置异常:{0}!", e.getMessage())); throw e; } } }

多数据源动态切换就大功告成!

你可能感兴趣的:(Java)