zoukankan      html  css  js  c++  java
  • mybatis plus + AOP 多数据源自动切换

    1. 数据库配置

    # .yml 文件
    spring:
      datasource:
        db1:
          type: com.alibaba.druid.pool.DruidDataSource
          driver-class-name: com.mysql.cj.jdbc.Driver
          jdbc-url: jdbc-url      # 配置
          username: root
          password: psw
        db2:
          type: com.alibaba.druid.pool.DruidDataSource
          driver-class-name: com.mysql.cj.jdbc.Driver
          jdbc-url: jdbc-url     # 配置
          username: root
          password: psw

    2. 数据源枚举类

    public enum DataSourceEnums {
    
        PRIMARY("primaryDataSource"),
        SECOND("secondDataSource");
    
        private String value;
    
        DataSourceEnums(String value){this.value=value;}
    
        public String getValue() {
            return value;
        }
    
    }

    3. mybatis plus Config 数据源切换类

    @Configuration
    @MapperScan(value = {"com.example.demo.dao"})
    public class MybatisPlusConfig {
    
        @Bean(name = "primaryDataSource")
        @ConfigurationProperties(prefix = "spring.datasource.db1")
        public DataSource primaryDataSource() {
            return DataSourceBuilder.create().build();
        }
    
        @Bean(name = "secondDataSource")
        @ConfigurationProperties(prefix = "spring.datasource.db2")
        public DataSource secondDataSource() {
            return DataSourceBuilder.create().build();
        }
    
        @Bean(name = "multipleTransactionManager")
        @Primary
        public DataSourceTransactionManager multipleTransactionManager(@Qualifier("multipleDataSource") DataSource dataSource) {
            return new DataSourceTransactionManager(dataSource);
        }
    
        /**
         * 动态数据源配置
         */
        @Bean(name = "multipleDataSource")
        @Primary
        public DataSource multipleDataSource(@Qualifier("primaryDataSource") DataSource primaryDataSource,
                                             @Qualifier("secondDataSource") DataSource secondDataSource) {
            DataSourceContextHolder dynamicDataSource = new DataSourceContextHolder();
            Map<Object, Object> targetDataSources = new HashMap<>();
            targetDataSources.put(DataSourceEnums.PRIMARY.getValue(), primaryDataSource);
            targetDataSources.put(DataSourceEnums.SECOND.getValue(), secondDataSource);
            dynamicDataSource.setTargetDataSources(targetDataSources);
            dynamicDataSource.setDefaultTargetDataSource(secondDataSource); // 程序默认数据源,这个要根据程序调用数据源频次,经常把常调用的数据源作为默认
            return dynamicDataSource;
        }
    
        @Bean("sqlSessionFactory")
        public SqlSessionFactory sqlSessionFactory() throws Exception {
            MybatisSqlSessionFactoryBean sqlSessionFactory = new MybatisSqlSessionFactoryBean();
            sqlSessionFactory.setDataSource(multipleDataSource(primaryDataSource(), secondDataSource()));
    
            MybatisConfiguration configuration = new MybatisConfiguration();
            configuration.setJdbcTypeForNull(JdbcType.NULL);
            //是否使用转驼峰
            configuration.setMapUnderscoreToCamelCase(true);
            configuration.setCacheEnabled(false);
            sqlSessionFactory.setConfiguration(configuration);//扫描 mapper 路径
            ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
            Resource[] resource = resolver.getResources("classpath:mapper/**/*.xml");
            sqlSessionFactory.setMapperLocations(resource);
            return sqlSessionFactory.getObject();
        }
    }

     3. DataSource 数据源获取类

    import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
    
    @Slf4j
    public class DataSourceContextHolder extends AbstractRoutingDataSource {
        public static final ThreadLocal<String> contextHolder = new ThreadLocal<String>();
    
        /**
         * 获取数据源
         */
        @Override
        protected Object determineCurrentLookupKey() {
            log.info("当前选择的数据源是:" + contextHolder.get());
            return contextHolder.get();
        }
    
        /**
         *  设置数据源*/
        public static void setDataSource(String db){
            contextHolder.set(db);
        }
    
        /**
         * 取得当前数据源
         * @return
         */
        public static String getDataSource(){
            return contextHolder.get();
        }
    
        /**
         * 清除上下文数据
         */
        public static void clear(){
            contextHolder.remove();
        }
    
    }

    4. AOP切面

    import com.example.demo.config.DataSourceContextHolder;
    import com.example.demo.enums.DataSourceEnums;
    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 AOP {
    
        /**
         * mybatis plus 动态切换数据源
         * */
        // 定义切点
        @Before("execution(* com.example.demo.dao.db1..*(..))")
        public void db1() {
            log.info("数据源切换到db1...");
            DataSourceContextHolder.setDataSource(DataSourceEnums.PRIMARY.getValue());
        }
    
        @Before("execution(* com.example.demo.dao.db2..*(..))")
        public void db2() {
            log.info("数据源切换到db2...");
            DataSourceContextHolder.setDataSource(DataSourceEnums.SECOND.getValue());
        }
    
    }
  • 相关阅读:
    oracle 主键自动地址实现
    解构赋值
    那些朋友那些话系列
    那些朋友那些话
    白鹭记事
    该如何存在
    上海秋季HCC小记
    For the person you never see again
    寻城记
    2013年的国庆
  • 原文地址:https://www.cnblogs.com/javencs/p/12966793.html
Copyright © 2011-2022 走看看