zoukankan      html  css  js  c++  java
  • springBoot双数据源配置

    当一个项目中需要调用两个数据库时,这个时候就需要配置双数据源。

    先配置配置文件

    然后再Application类上加入:

    @SpringBootApplication(
            exclude = {
                    DataSourceAutoConfiguration.class
            }
    )这个注解去除掉默认的数据库配置,然后我们自己去配置database.
    

    DataSourceConfig类:

    import org.springframework.boot.context.properties.ConfigurationProperties;
    import org.springframework.boot.jdbc.DataSourceBuilder;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.Primary;
    import org.springframework.jdbc.datasource.DataSourceTransactionManager;
    import org.springframework.transaction.PlatformTransactionManager;
    
    import javax.sql.DataSource;
    import java.util.HashMap;
    import java.util.Map;
    
    /**
     * @Author: ch
     * @Date: 2018/6/27 11:06
     * @Description:
     */
    @Configuration
    public class DataSourceConfig {
    
        @Bean(name = "db")
        @ConfigurationProperties(prefix = "spring.datasource.db")
        public DataSource dataSource1() {
            return DataSourceBuilder.create().build();
        }
    
        @Bean(name = "db2")
        @ConfigurationProperties(prefix = "spring.datasource.db2")
        public DataSource dataSource2() {
            return DataSourceBuilder.create().build();
        }
    
        /**
         * 动态数据源: 通过AOP在不同数据源之间动态切换
         *
         * @return
         */
        @Primary
        @Bean(name = "dynamicDS1")
        public DataSource dataSource() {
            DynamicDataSource dynamicDataSource = new DynamicDataSource();
            // 默认数据源
            dynamicDataSource.setDefaultTargetDataSource(dataSource1());
    
            // 配置多数据源
            Map<Object, Object> dsMap = new HashMap(5);
            dsMap.put("db", dataSource1());
            dsMap.put("db2", dataSource2());
    
            dynamicDataSource.setTargetDataSources(dsMap);
            return dynamicDataSource;
        }
        /**
         * 配置@Transactional注解事物
         * @return
         */
        @Bean
        public PlatformTransactionManager transactionManager() {
            return new DataSourceTransactionManager(dataSource());
        }
    }

    DynamicDataSource 类

    import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
    
    /**
     * @Author: ch
     * @Date: 2018/6/27 11:40
     * @Description:
     */
    public class DynamicDataSource extends AbstractRoutingDataSource {
        @Override
        protected Object determineCurrentLookupKey() {
            return DataSourceContextHolder.getDB();
        }
    }

    DynamicDataSourceAspect 类

    import org.aspectj.lang.JoinPoint;
    import org.aspectj.lang.annotation.After;
    import org.aspectj.lang.annotation.Aspect;
    import org.aspectj.lang.annotation.Before;
    import org.aspectj.lang.reflect.MethodSignature;
    import org.springframework.stereotype.Component;
    
    import java.lang.reflect.Method;
    
    /**
     * @Author: ch
     * @Date: 2018/6/27 11:48
     * @Description:
     */
    @Aspect
    @Component
    public class DynamicDataSourceAspect {
    
        @Before("@annotation(DS)")
        public void beforeSwitchDS(JoinPoint point){
    
            //获得当前访问的class
            Class<?> className = point.getTarget().getClass();
    
            //获得访问的方法名
            String methodName = point.getSignature().getName();
            //得到方法的参数的类型
            Class[] argClass = ((MethodSignature)point.getSignature()).getParameterTypes();
            String dataSource = DataSourceContextHolder.DEFAULT_DS;
            try {
                // 得到访问的方法对象
                Method method = className.getMethod(methodName, argClass);
    
                // 判断是否存在@DS注解
                if (method.isAnnotationPresent(DS.class)) {
                    DS annotation = method.getAnnotation(DS.class);
                    // 取出注解中的数据源名
                    dataSource = annotation.value();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            // 切换数据源
            DataSourceContextHolder.setDB(dataSource);
    
        }
    
    
        @After("@annotation(DS)")
        public void afterSwitchDS(JoinPoint point){
            DataSourceContextHolder.clearDB();
    
        }
    }

    DataSourceContextHolder 类

    public class DataSourceContextHolder {
        /**
         * 默认数据源
         */
        public static final String DEFAULT_DS = "db";
    
        private static final ThreadLocal<String> contextHolder = new ThreadLocal<>();
    
        // 设置数据源名
        public static void setDB(String dbType) {
            contextHolder.set(dbType);
        }
    
        // 获取数据源名
        public static String getDB() {
            return (contextHolder.get());
        }
    
        // 清除数据源名
        public static void clearDB() {
            contextHolder.remove();
        }
    }

    DS 类

    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    
    /**
     * @Author: ch
     * @Date: 2018/6/27 11:47
     * @Description:
     */
    @Retention(RetentionPolicy.RUNTIME)
    @Target({
            ElementType.METHOD
    })
    public @interface DS {
        String value() default "db";
    }

    默认的数据库在调用的时候不用加任何的东西,按照正常的方式去使用即可,而使用到第二个数据库的serviceImpl的方法上加上

    @DS("db2")即可,这样这个方法中的mapper文件就会调用不是默认的那个数据库了。


    转载至https://blog.csdn.net/haha_66666/article/details/81507416
  • 相关阅读:
    数据挖掘专业术语
    Python 随机数用法
    精通Web Analytics 2.0 (8) 第六章:使用定性数据解答”为什么“的谜团
    建模前的数据清洗/ETL(python)
    [分类算法] :朴素贝叶斯 NaiveBayes
    DSP, SSP, DMP
    laravel路由
    Laravel 5 中的配置
    Jquery的each遍历数据组成JSON
    JS上传图片预览及图片限制
  • 原文地址:https://www.cnblogs.com/lhn9527/p/13964237.html
Copyright © 2011-2022 走看看