配置多数据源

Posted sun27

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了配置多数据源相关的知识,希望对你有一定的参考价值。

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();



 
 

 

以上是关于配置多数据源的主要内容,如果未能解决你的问题,请参考以下文章

多数据源 spring怎么管理事务的

Spring动态配置多数据源的基于spring和ibatis的多数据源切换方案

Spring Boot 配置多数据源

springboot+mybatis+Druid配置多数据源(mysql+postgre)

Druid连接池配置多数据源

Mybatis+Druid多数据源配置