zoukankan      html  css  js  c++  java
  • springboot+druid+mybatis plus的多数据源配置

    思路

    1. yml中配置多个数据源信息
    2. 通过AOP切换不同数据源
    3. 配合mybatis plus使用

    POM依赖

    <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配置

    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

    启动加载多个数据源

    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 的性能优化
         */
        @Bean
        public PerformanceInterceptor performanceInterceptor() {
            PerformanceInterceptor performanceInterceptor = new PerformanceInterceptor();
            /* <!-- SQL 执行性能分析,开发环境使用,线上不推荐。 maxTime 指的是 sql 最大执行时长 --> */
            //performanceInterceptor.setMaxTime(1000);
            /* <!--SQL是否格式化 默认false--> */
            performanceInterceptor.setFormat(false);
            return performanceInterceptor;
        }
    
        /**
         * mybatis-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枚举类

    public enum DBTypeEnum {
        ES("es"), WX("wx");
        private String value;
    
        DBTypeEnum(String value) {
            this.value = value;
        }
    
        public String getValue() {
            return value;
        }
    }

    动态数据源决策

    import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
    
    public class DynamicDataSource extends AbstractRoutingDataSource {
        /**
         * 取得当前使用哪个数据源
         * @return
         */
        @Override
        protected Object determineCurrentLookupKey() {
            return DbContextHolder.getDbType();
        }
    }

    设置、获取数据源

    public class DbContextHolder {
        private static final ThreadLocal contextHolder = new ThreadLocal<>();
        /**
         * 设置数据源
         * @param dbTypeEnum
         */
        public static void setDbType(DBTypeEnum dbTypeEnum) {
            contextHolder.set(dbTypeEnum.getValue());
        }
    
        /**
         * 取得当前数据源
         * @return
         */
        public static String getDbType() {
            return (String) contextHolder.get();
        }
    
        /**
         * 清除上下文数据
         */
        public static void clearDbType() {
            contextHolder.remove();
        }
    }

    AOP实现的数据源切换

    import lombok.extern.slf4j.Slf4j;
    import org.aspectj.lang.annotation.*;
    import org.springframework.core.annotation.Order;
    import org.springframework.stereotype.Component;
    
    @Component
    @Aspect
    @Order(-100) //这是为了保证AOP在事务注解之前生效,Order的值越小,优先级越高
    @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("切换到ES 数据源...");
            DbContextHolder.setDbType(DBTypeEnum.ES);
        }
    
        @Before("jarvisWxAspect()")
        public void jarvisWxDb () {
            log.info("切换到WX 数据源...");
            DbContextHolder.setDbType(DBTypeEnum.WX);
        }
    }

    mapper层结构

     参考

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

  • 相关阅读:
    [svc]二三层数据格式&&三层数据如何匹配路由
    [na][dhcp]dhcp细枝末节&dhcp防攻
    [docker]使用quaaga实现(rip ospf)实现主机间容器互通
    [svc]centos7安装优化最佳姿势
    [svc]gns3模拟器及探讨几个bgp问题
    [svc]ip routing和no ip routing
    [docker]macvlan实现双vlan互通
    Jmeter 日志设置---如何设置java协议中被测jar的日志?
    Jmeter java协议配置文件导入
    eclipse, Log4j配置(真心的详细~)
  • 原文地址:https://www.cnblogs.com/szwdun/p/11263201.html
Copyright © 2011-2022 走看看