• springboot配置多数据源


    1.yml配置:

    spring:
    datasource:
    his:
    driver-class-name: com.mysql.cj.jdbc.Driver
    password: aa
    jdbc-url: jdbc:mysql://aa:3306/aa?useUnlcode=1&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true&remarksReporting=true&serverTimezone=GMT%2B8
    username: aa
    gym:
    driver-class-name: com.mysql.cj.jdbc.Driver
    password: bb
    jdbc-url: jdbc:mysql://bb/bb?useUnlcode=1&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true&remarksReporting=true&serverTimezone=GMT%2B8
    username: bb
    package com.gymexpress.histar.config;

    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;

    2.多数据源配置类

    /**
    * @author
    * 多数据源配置类
    */
    @Configuration
    public class DataSourceConfig {
    /**
    * 数据源exgym_new
    * @return
    */
    @Bean(name="dataSourceHis")
    @ConfigurationProperties(prefix = "spring.datasource.his")
    public DataSource dataSourceHis(){
    return DataSourceBuilder.create().build();
    }

    /**
    * 数据源gym
    * @return
    */
    @Bean(name="dataSourceGym")
    @ConfigurationProperties(prefix = "spring.datasource.gym")
    public DataSource dataSourceGym(){
    return DataSourceBuilder.create().build();
    }

    /**
    * 动态数据源:通过aop在不同的数据源之间动态切换
    * @return
    */
    @Primary
    @Bean(name="dynamicDataSource")
    public DataSource dynamicDataSource(){
    DynamicDataSource dynamicDataSource=new DynamicDataSource();
    //默认数据源
    dynamicDataSource.setDefaultTargetDataSource(dataSourceHis());
    //配置多数据源
    Map<Object,Object> dsMap=new HashMap<>();
    dsMap.put("dataSourceHis",dataSourceHis());
    dsMap.put("dataSourceGym",dataSourceGym());
    dynamicDataSource.setTargetDataSources(dsMap);
    return dynamicDataSource;
    }

    /**
    * 配置@transactional注解事务
    * @return
    */
    @Bean
    public PlatformTransactionManager transactionManager(){
    return new DataSourceTransactionManager(dynamicDataSource());
    }
    }

    3.配置默认数据源
    package com.gymexpress.histar.config;

    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;

    public class DataSourceContextHolder {

    private static final Logger LOGGER= LoggerFactory.getLogger(DataSourceContextHolder.class);

    /**
    * 默认数据源
    */
    public static final String DEFAULT_DS="dataSourceHis";

    /**

    * 当使用ThreadLocal维护变量时,ThreadLocal为每个使用该变量的线程提供独立的变量副本,

    * 所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本。

    */
    private static final ThreadLocal<String> contextHolder=new ThreadLocal<>();

    /**
    * 设置数据库名
    * @param dbType
    */
    public static void setDB(String dbType){
    LOGGER.info("切换到{"+dbType+"}数据源");
    contextHolder.set(dbType);
    }

    /**
    * 获取数据源名
    * @return
    */
    public static String getDB(){
    return (contextHolder.get());
    }

    /**
    * 清楚数据源
    */
    public static void clearDB(){
    contextHolder.remove();
    }
    }

    4.自定义注解
    package com.gymexpress.histar.config;

    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;

    /**
    * @author
    * 自定义注解
    */
    @Retention(RetentionPolicy.RUNTIME)
    @Target({ElementType.METHOD})
    public @interface DS {

    /**
    * 默认His数据库
    * @return
    */
    String value() default "dataSourceHis";

    }
    5.获取数据源
    package com.gymexpress.histar.config;

    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;

    /**
    * @author
    *
    */
    public class DynamicDataSource extends AbstractRoutingDataSource {

    private static final Logger LOGGER= LoggerFactory.getLogger(DynamicDataSource.class);

    @Override
    protected Object determineCurrentLookupKey() {
    LOGGER.info("数据源为:"+DataSourceContextHolder.getDB());
    return DataSourceContextHolder.getDB();
    }
    }
    6.切换数据源
    package com.gymexpress.histar.config;

    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.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.stereotype.Component;

    import java.lang.reflect.Method;

    /**
    * 自定义注解 + AOP的方式实现数据源动态切换。
    * @author
    *
    */
    @Aspect
    @Component
    public class DynamicDataSourceAspect {
    private static final Logger LOGGER= LoggerFactory.getLogger(DynamicDataSourceAspect.class);

    @Before("@annotation(DS)")
    public void beforeSwitchDS(JoinPoint point){
    //获得当前访问的class
    Class<?> className = point.getTarget().getClass();
    //获得访问的方法名
    String name = point.getSignature().getName();
    //得到方法参数的类型
    Class[] parameterTypes = ((MethodSignature) point.getSignature()).getParameterTypes();
    String datasource = DataSourceContextHolder.DEFAULT_DS;
    try {
    //得到访问的方法对象
    Method method = className.getMethod(name, parameterTypes);
    //判断是否存在@DS注解
    if(method.isAnnotationPresent(DS.class)){
    DS annotation = method.getAnnotation(DS.class);
    //取出注解中的数据源名
    datasource = annotation.value();
    }
    }catch (Exception e){
    LOGGER.error(e.toString(),e);

    }
    //切换数据源
    DataSourceContextHolder.setDB(datasource);
    }

    @After("@annotation(DS)")
    public void afterSwitchDs(JoinPoint joinPoint){
    DataSourceContextHolder.clearDB();
    }
    }

     
     
  • 相关阅读:
    Java中的国际化
    springcloud介绍
    SpringMVC之请求和响应
    JAVA坦克大战系列10-高效雷达(下)
    CF920F SUM and REPLACE
    luoguP4141 消失之物
    luoguP2843 暗杀
    luoguP5521 [yLOI2019] 梅深不见冬
    CF940E Cashback
    CF1051D Bicolorings
  • 原文地址:https://www.cnblogs.com/sun27/p/11326347.html
Copyright © 2020-2023  润新知