配置多数据源

亡梦爱人 提交于 2019-11-26 16:17:32

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 * 多数据源配置类 */@Configurationpublic 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@Componentpublic 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();    }}
 
 

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!