使用案例
//添加到方法上面即可
@TargetDatasource("oh")
public int addDataConfigCatalog(DiitResourceCatalog dataCatalog) {
return insertNumber;
}
@TargetDatasource("oh")
public int deleteDataConfigCatalog(String catalogIds) {
return deleteNumber;
}
@TargetDatasource("oh")
public List<Map<String, String>> getLastYearUpdateCount(String catalogId) {
List<Map<String, String>> lastYearUpdateCount = dataConfigCatalogMapper.getLastYearUpdateCount(catalogId);
return lastYearUpdateCount;
}
TargetDatasource 注解
package diit.platform.bussiness.datasource;
import java.lang.annotation.*;
/*
* 在方法上使用,表示使用哪个数据源,数据源注入注释
* @author hm
* */
@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface TargetDatasource {
String value();
}
动态数据源注册 DynamicDataSourceRegister
package diit.platform.bussiness.datasource;
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.pool.DruidDataSourceFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.PropertyValues;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.GenericBeanDefinition;
import org.springframework.boot.bind.RelaxedDataBinder;
import org.springframework.boot.bind.RelaxedPropertyResolver;
import org.springframework.context.EnvironmentAware;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.env.Environment;
import org.springframework.core.type.AnnotationMetadata;
import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;
/**
* 动态数据源注册
* @author hm
*/
public class DynamicDataSourceRegister implements ImportBeanDefinitionRegistrar, EnvironmentAware{
private static final Logger logger = LoggerFactory.getLogger(DynamicDataSourceRegister.class);
// 数据源配置信息
private PropertyValues dataSourcePropertyValues;
// 默认数据源
private DataSource defaultDataSource;
// 动态数据源
private Map<String, DataSource> dynamicDataSources = new HashMap<>();
/**
* 加载多数据源配置
*/
@Override
public void setEnvironment(Environment env) {
RelaxedPropertyResolver propertyResolver = new RelaxedPropertyResolver(env, "jdbc.");
String dsPrefixs = propertyResolver.getProperty("datasources");
for (String dsPrefix : dsPrefixs.split(",")) {// 多个数据源
Map<String, Object> map = propertyResolver.getSubProperties(dsPrefix + ".");
DataSource ds = initDataSource(map);
// 设置默认数据源
if ("xjhjpt".equals(dsPrefix)) {
defaultDataSource = ds;
} else {
dynamicDataSources.put(dsPrefix, ds);
}
dataBinder(ds, env);
}
}
/*
* 初始化数据源
* @param map
* @reurn
*/
@SuppressWarnings("unchecked")
public DataSource initDataSource(Map<String, Object> map) {
DruidDataSource dataSource = null;
try {
dataSource = (DruidDataSource) DruidDataSourceFactory.createDataSource(map);
dataSource.setInitialSize(3);
dataSource.setMaxActive(15);
dataSource.setMinIdle(3);
dataSource.setMaxWait(60000L);
dataSource.setTimeBetweenEvictionRunsMillis(60000L);
dataSource.setTimeBetweenLogStatsMillis(300000L);
dataSource.setMinEvictableIdleTimeMillis(300000L);
dataSource.setTestWhileIdle(true);
dataSource.setTestOnBorrow(false);
dataSource.setTestOnReturn(false);
dataSource.setTimeBetweenConnectErrorMillis(60000L); //连接出错过60秒重新尝试
} catch (Exception e) {
e.printStackTrace();
}
return dataSource;
}
/**
* 加载数据源配置信息
* @param dataSource
* @param env
*/
private void dataBinder(DataSource dataSource, Environment env) {
RelaxedDataBinder dataBinder = new RelaxedDataBinder(dataSource);
dataBinder.setIgnoreNestedProperties(false);// false
dataBinder.setIgnoreInvalidFields(false);// false
dataBinder.setIgnoreUnknownFields(true);// true
if (dataSourcePropertyValues == null) {
Map<String, Object> values = new RelaxedPropertyResolver(env, "datasource").getSubProperties(".");
dataSourcePropertyValues = new MutablePropertyValues(values);
}
dataBinder.bind(dataSourcePropertyValues);
}
/**
* 注册数据源been
*/
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
Map<Object, Object> targetDataSources = new HashMap<Object, Object>();
// 将主数据源添加到更多数据源中
targetDataSources.put("dataSource", defaultDataSource);
// 添加更多数据源
targetDataSources.putAll(dynamicDataSources);
// 创建DynamicDataSource
GenericBeanDefinition beanDefinition = new GenericBeanDefinition();
beanDefinition.setBeanClass(DynamicDataSource.class);
beanDefinition.setSynthetic(true);
MutablePropertyValues mpv = beanDefinition.getPropertyValues();
mpv.addPropertyValue("defaultTargetDataSource", defaultDataSource);
mpv.addPropertyValue("targetDataSources", targetDataSources);
registry.registerBeanDefinition("dataSource", beanDefinition);
logger.info("多数据源注册成功");
}
}
切换数据源 DynamicDataSourceAspect
package diit.platform.bussiness.datasource;
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.springframework.stereotype.Component;
/*
* 切换数据源
* @author hm
* */
@Aspect
@Component
public class DynamicDataSourceAspect {
@Before("@annotation(ds)")
public void changeDataSource(JoinPoint point,TargetDatasource ds) {
DynamicDataSource.setDataSourceType(ds.value());
}
@After("@annotation(ds)")
public void restoreDataSource(JoinPoint point,TargetDatasource ds) {
DynamicDataSource.clearDataSourceType();
}
}
动态设置数据源 DynamicDataSource
package diit.platform.bussiness.datasource;
import lombok.extern.log4j.Log4j;
import lombok.extern.slf4j.Slf4j;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
/*
* 动态设置数据源
* @author hm
* */
@Slf4j
public class DynamicDataSource extends AbstractRoutingDataSource{
private static final ThreadLocal<String>contextHolder=new ThreadLocal<String>();
public static void setDataSourceType(String datasourceType) {
contextHolder.set(datasourceType);
}
public static String getDataSourceType() {
// TODO Auto-generated method stub
return contextHolder.get();
}
public static void clearDataSourceType() {
contextHolder.remove();
}
@Override
protected Object determineCurrentLookupKey() {
// TODO Auto-generated method stub
return getDataSourceType();
}
}
application.properties
jdbc.datasources=xjhjpt,ssba,kjfx,oh
jdbc.xjhjpt.driverClassName=oracle.jdbc.OracleDriver
jdbc.xjhjpt.url=jdbc:oracle:thin:@test2.diit.cn:4215/orcl
jdbc.xjhjpt.username=USE_HXK_XJHJ
jdbc.xjhjpt.password=USE_HXK_XJHJ
jdbc.ssba.driverClassName=oracle.jdbc.OracleDriver
jdbc.ssba.url=jdbc:oracle:thin:@test2.diit.cn:4215/orcl
jdbc.ssba.username=USE_ZTK
jdbc.ssba.password=USE_ZTK
jdbc.kjfx.driverClassName=oracle.jdbc.OracleDriver
jdbc.kjfx.url=jdbc:oracle:thin:@test2.diit.cn:4215/orcl
jdbc.kjfx.username=USE_HXK_XJHJ_KJ
jdbc.kjfx.password=USE_HXK_XJHJ_KJ
jdbc.oh.driverClassName=org.postgresql.Driver
jdbc.oh.url=jdbc:postgresql://192.9.30.225:5432/xinjiang_huiju_data_overview
jdbc.oh.username=postgres
jdbc.oh.password=postgres