Browse Source

动态数据源-支持参数方式指定数据源

dev
wxz 5 years ago
parent
commit
f9e1a07e7c
  1. 6
      epmet-commons/epmet-commons-dynamic-datasource/pom.xml
  2. 46
      epmet-commons/epmet-commons-dynamic-datasource/src/main/java/com/epmet/commons/dynamic/datasource/aspect/DataSourceAspect.java
  3. 8
      epmet-commons/epmet-commons-dynamic-datasource/src/main/java/com/epmet/commons/dynamic/datasource/config/DynamicDataSource.java
  4. 43
      epmet-commons/epmet-commons-dynamic-datasource/src/main/java/com/epmet/commons/dynamic/datasource/enums/DataSourceEnum.java
  5. 13
      epmet-commons/epmet-commons-dynamic-datasource/src/main/java/com/epmet/commons/dynamic/datasource/util/AbstractDataSourceNameFetcher.java
  6. 44
      epmet-commons/epmet-commons-dynamic-datasource/src/main/java/com/epmet/commons/dynamic/datasource/util/HttpRequestDataSourceNameFetcher.java
  7. 1
      epmet-module/data-statistical/data-statistical-client/src/main/java/com/epmet/constant/DataSourceConstant.java
  8. 17
      epmet-module/data-statistical/data-statistical-server/src/main/java/com/epmet/controller/DemoController.java
  9. 3
      epmet-module/data-statistical/data-statistical-server/src/main/java/com/epmet/service/stats/impl/DimAgencyServiceImpl.java
  10. 10
      epmet-module/data-statistical/data-statistical-server/src/main/resources/bootstrap.yml
  11. 1
      epmet-module/data-statistical/data-statistical-server/src/main/resources/mapper/stats/DimAgencyDao.xml

6
epmet-commons/epmet-commons-dynamic-datasource/pom.xml

@ -19,6 +19,12 @@
<version>2.0.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
<build>

46
epmet-commons/epmet-commons-dynamic-datasource/src/main/java/com/epmet/commons/dynamic/datasource/aspect/DataSourceAspect.java

@ -9,8 +9,8 @@
package com.epmet.commons.dynamic.datasource.aspect;
import com.epmet.commons.dynamic.datasource.annotation.DataSource;
import com.epmet.commons.dynamic.datasource.bean.DataSourceParam;
import com.epmet.commons.dynamic.datasource.config.DynamicContextHolder;
import com.epmet.commons.dynamic.datasource.util.HttpRequestDataSourceNameFetcher;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
@ -19,12 +19,12 @@ import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
/**
* 多数据源切面处理类
@ -38,6 +38,9 @@ import java.lang.reflect.Parameter;
public class DataSourceAspect {
protected Logger logger = LoggerFactory.getLogger(getClass());
@Autowired
private HttpRequestDataSourceNameFetcher httpRequestDataSourceNameFetcher;
@Pointcut("@annotation(com.epmet.commons.dynamic.datasource.annotation.DataSource) " +
"|| @within(com.epmet.commons.dynamic.datasource.annotation.DataSource)")
public void dataSourcePointCut() {
@ -55,12 +58,14 @@ public class DataSourceAspect {
if(targetDataSource != null || methodDataSource != null){
String value;
if(methodDataSource != null){
value = getDatasourceName(methodDataSource, signature.getMethod().getParameters(), point.getArgs());
value = getDatasourceName(methodDataSource);
}else {
value = getDatasourceName(targetDataSource, signature.getMethod().getParameters(), point.getArgs());
value = getDatasourceName(targetDataSource);
}
if (StringUtils.isNotBlank(value)) {
DynamicContextHolder.push(value);
}
logger.debug("set datasource is {}", value);
}
@ -77,33 +82,16 @@ public class DataSourceAspect {
* @param dataSource
* @return
*/
public String getDatasourceName(DataSource dataSource, Parameter[] methodParameters, Object[] methodArgValues) {
public String getDatasourceName(DataSource dataSource) {
String dataSourceName = null;
if (dataSource.datasourceNameFromArg()) {
// 1.从参数中动态获取数据源名称
String datasourceNameFromParam = getDatasourceNameFromArg(methodParameters, methodArgValues);
if (StringUtils.isNotBlank(datasourceNameFromParam)) {
// 如果有DatasourceParam类型的参数并且设置了datasourceName值,那么返回这个值,否则使用硬编码的
return datasourceNameFromParam;
}
}
// 2.硬编码指定数据源名称
return dataSource.value();
}
/**
* 从参数中取数据源名称
* @param parameters
* @param argsObject
* @return
*/
public String getDatasourceNameFromArg(Parameter[] parameters, Object[] argsObject) {
for (int i = 0; i < parameters.length; i++) {
if (parameters[i].getType() == DataSourceParam.class) {
DataSourceParam param = (DataSourceParam) argsObject[i];
return param.getDatasourceName();
// 1.优先从http header中动态获取数据源名称
dataSourceName = httpRequestDataSourceNameFetcher.fetchDataSourceName();
}
// 2.硬编码指定默认的数据源名称
if (StringUtils.isBlank(dataSourceName)) {
dataSourceName = dataSource.value();
}
return null;
return dataSourceName;
}
}

8
epmet-commons/epmet-commons-dynamic-datasource/src/main/java/com/epmet/commons/dynamic/datasource/config/DynamicDataSource.java

@ -8,6 +8,8 @@
package com.epmet.commons.dynamic.datasource.config;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
/**
@ -18,9 +20,13 @@ import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
*/
public class DynamicDataSource extends AbstractRoutingDataSource {
private Logger logger = LoggerFactory.getLogger(getClass());
@Override
protected Object determineCurrentLookupKey() {
return DynamicContextHolder.peek();
String datasourceName = DynamicContextHolder.peek();
logger.info("使用的数据源名称为:{}", datasourceName);
return datasourceName;
}
}

43
epmet-commons/epmet-commons-dynamic-datasource/src/main/java/com/epmet/commons/dynamic/datasource/enums/DataSourceEnum.java

@ -0,0 +1,43 @@
package com.epmet.commons.dynamic.datasource.enums;
/**
* 服务-数据源flag-数据源名称对应关系
*/
public enum DataSourceEnum {
DATA_STATISTICAL_REAL("data-statistical-server", "real", "stats"),
DATA_STATISTICAL_FAKE("data-statistical-server", "fake", "statsDisplay"),
;
private String serviceName;
private String flag;
private String dataSourceName;
DataSourceEnum(String serviceName, String flag, String dataSourceName) {
this.serviceName = serviceName;
this.flag = flag;
this.dataSourceName = dataSourceName;
}
public static DataSourceEnum getEnum(String serviceName, String flag) {
DataSourceEnum[] values = DataSourceEnum.values();
for (DataSourceEnum value : values) {
if (value.serviceName.equals(serviceName) && value.flag.equals(flag)) {
return value;
}
}
return null;
}
public String getServiceName() {
return serviceName;
}
public String getFlag() {
return flag;
}
public String getDataSourceName() {
return dataSourceName;
}
}

13
epmet-commons/epmet-commons-dynamic-datasource/src/main/java/com/epmet/commons/dynamic/datasource/util/AbstractDataSourceNameFetcher.java

@ -0,0 +1,13 @@
package com.epmet.commons.dynamic.datasource.util;
import com.epmet.commons.dynamic.datasource.enums.DataSourceEnum;
public abstract class AbstractDataSourceNameFetcher {
public abstract String fetchDataSourceName();
//protected String getDataSourceName(String dataType, String serviceName) {
// return DataSourceEnum.getEnum(serviceName, dataType)
//}
}

44
epmet-commons/epmet-commons-dynamic-datasource/src/main/java/com/epmet/commons/dynamic/datasource/util/HttpRequestDataSourceNameFetcher.java

@ -0,0 +1,44 @@
package com.epmet.commons.dynamic.datasource.util;
import com.epmet.commons.dynamic.datasource.enums.DataSourceEnum;
import com.epmet.commons.tools.exception.RenException;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
/**
* Http请求中获取数据源名称
*/
@Component
public class HttpRequestDataSourceNameFetcher extends AbstractDataSourceNameFetcher {
protected Logger logger = LoggerFactory.getLogger(getClass());
@Autowired
private Environment environment;
@Override
public String fetchDataSourceName() {
ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
javax.servlet.http.HttpServletRequest request = requestAttributes.getRequest();
String dataType = request.getHeader("Data-Type");
logger.info("HttpRequestDataSourceNameFetcher获取到的DataType为:{}", dataType);
if (StringUtils.isBlank(dataType)) {
return null;
}
String serviceName = environment.getProperty("spring.application.name");
DataSourceEnum dataSourceEnum = DataSourceEnum.getEnum(serviceName, dataType);
if (dataSourceEnum == null) {
throw new RenException(String.format("根据前端传入的DataType[%s]无法找到对应的数据源。", dataType));
}
logger.info("HttpRequestDataSourceNameFetcher根据DataType:[{}]获取到的DataSourceEnum为{}", dataType, dataSourceEnum.getDataSourceName());
return dataSourceEnum.getDataSourceName();
}
}

1
epmet-module/data-statistical/data-statistical-client/src/main/java/com/epmet/constant/DataSourceConstant.java

@ -4,6 +4,7 @@ public interface DataSourceConstant {
String GOV_ORG = "govOrg";
String STATS = "stats";
String STATS_DISPLAY = "statsDisplay";
String GOV_ISSUE = "govIssue";
String GOV_PROJECT = "govProject";
String GOV_VOICE = "govVoice";

17
epmet-module/data-statistical/data-statistical-server/src/main/java/com/epmet/controller/DemoController.java

@ -1,11 +1,15 @@
package com.epmet.controller;
import com.epmet.commons.tools.exception.RenException;
import com.epmet.commons.tools.utils.Result;
import com.epmet.dto.AgencySubTreeDto;
import com.epmet.entity.stats.DimAgencyEntity;
import com.epmet.service.StatsDemoService;
import com.epmet.service.stats.DimAgencyService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@ -26,6 +30,9 @@ public class DemoController {
@Autowired
private ExecutorService executorService;
@Autowired
private DimAgencyService dimAgencyService;
@GetMapping("testAlarm")
public void testAlarm() {
//for (int i = 0; i < 20; i++) {
@ -91,4 +98,14 @@ public class DemoController {
List<AgencySubTreeDto> result = demoService.getAllAgency();
return result;
}
/**
* 参数指定数据源
* @return
*/
@PostMapping("paramDataSource")
public Result paramDataSource() {
List<DimAgencyEntity> list = dimAgencyService.getAgencyListByCustomerId("ba7c0b5b21e882b263ee8456e2cfb63e");
return new Result().ok(list);
}
}

3
epmet-module/data-statistical/data-statistical-server/src/main/java/com/epmet/service/stats/impl/DimAgencyServiceImpl.java

@ -19,12 +19,14 @@ package com.epmet.service.stats.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.epmet.commons.dynamic.datasource.annotation.DataSource;
import com.epmet.commons.mybatis.service.impl.BaseServiceImpl;
import com.epmet.commons.tools.exception.EpmetErrorCode;
import com.epmet.commons.tools.exception.RenException;
import com.epmet.commons.tools.page.PageData;
import com.epmet.commons.tools.utils.ConvertUtils;
import com.epmet.commons.tools.constant.FieldConstant;
import com.epmet.constant.DataSourceConstant;
import com.epmet.constant.DimAgencyConstant;
import com.epmet.constant.RobotConstant;
import com.epmet.constant.StatsSubject;
@ -208,6 +210,7 @@ public class DimAgencyServiceImpl extends BaseServiceImpl<DimAgencyDao, DimAgenc
return baseDao.selectTopAgency(customerId);
}
@DataSource(value = DataSourceConstant.STATS, datasourceNameFromArg = true)
@Override
public List<DimAgencyEntity> getAgencyListByCustomerId(String customerId) {
if (StringUtils.isBlank(customerId)){

10
epmet-module/data-statistical/data-statistical-server/src/main/resources/bootstrap.yml

@ -155,6 +155,16 @@ dynamic:
url: @datasource.druid.user.url@
username: @datasource.druid.user.username@
password: @datasource.druid.user.password@
stats:
driver-class-name: com.mysql.cj.jdbc.Driver
url: @datasource.druid.stats.url@
username: @datasource.druid.stats.username@
password: @datasource.druid.stats.password@
statsDisplay:
driver-class-name: com.mysql.cj.jdbc.Driver
url: @datasource.druid.statsdisplay.url@
username: @datasource.druid.statsdisplay.username@
password: @datasource.druid.statsdisplay.password@
thread:
# 线程池配置

1
epmet-module/data-statistical/data-statistical-server/src/main/resources/mapper/stats/DimAgencyDao.xml

@ -128,6 +128,7 @@
ID,
CUSTOMER_ID,
PID,
AGENCY_NAME,
LEVEL
FROM
dim_agency

Loading…
Cancel
Save