commit:VO支持以及bug修复

This commit is contained in:
Jerry
2020-12-18 22:52:35 +08:00
parent ecec5ae30a
commit d86ae86f1c
558 changed files with 8019 additions and 10785 deletions

View File

@@ -1,8 +1,6 @@
package com.orange.demo.common.core.advice;
import com.orange.demo.common.core.exception.InvalidClassFieldException;
import com.orange.demo.common.core.exception.InvalidDataFieldException;
import com.orange.demo.common.core.exception.InvalidDataModelException;
import com.orange.demo.common.core.exception.*;
import com.orange.demo.common.core.constant.ErrorCodeEnum;
import com.orange.demo.common.core.exception.RedisCacheAccessException;
import com.orange.demo.common.core.object.ResponseResult;
@@ -113,6 +111,19 @@ public class MyExceptionHandler {
return ResponseResult.error(ErrorCodeEnum.DATA_ACCESS_FAILED);
}
/**
* 操作不存在或已逻辑删除数据的异常处理方法。
*
* @param ex 异常对象。
* @param request http请求。
* @return 应答对象。
*/
@ExceptionHandler(value = NoDataAffectException.class)
public ResponseResult<Void> noDataEffectExceptionHandle(Exception ex, HttpServletRequest request) {
log.error("NoDataAffectException exception from URL [" + request.getRequestURI() + "]", ex);
return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST);
}
/**
* Redis缓存访问异常处理方法。
*

View File

@@ -1,9 +1,6 @@
package com.orange.demo.common.core.base.client;
import com.orange.demo.common.core.object.MyAggregationParam;
import com.orange.demo.common.core.object.MyQueryParam;
import com.orange.demo.common.core.object.ResponseResult;
import com.orange.demo.common.core.object.Tuple2;
import com.orange.demo.common.core.object.*;
import java.util.*;
@@ -11,11 +8,12 @@ import java.util.*;
* 远程调用接口。
*
* @param <D> 主DomainDto域数据对象类型。
* @param <V> 主DomainVo域数据对象类型。
* @param <K> 主键类型。
* @author Jerry
* @date 2020-08-08
*/
public interface BaseClient<D, K> {
public interface BaseClient<D, V, K> {
/**
* 基于主键的(in list)获取远程数据接口。
@@ -24,7 +22,7 @@ public interface BaseClient<D, K> {
* @param withDict 是否包含字典关联。
* @return 应答结果对象,包含主对象集合。
*/
ResponseResult<List<D>> listByIds(Set<K> filterIds, Boolean withDict);
ResponseResult<List<V>> listByIds(Set<K> filterIds, Boolean withDict);
/**
* 基于主键Id获取远程对象。
@@ -33,7 +31,7 @@ public interface BaseClient<D, K> {
* @param withDict 是否包含字典关联。
* @return 应答结果对象,包含主对象数据。
*/
ResponseResult<D> getById(K id, Boolean withDict);
ResponseResult<V> getById(K id, Boolean withDict);
/**
* 判断参数列表中指定的主键Id是否全部存在。
@@ -76,9 +74,9 @@ public interface BaseClient<D, K> {
* 缺省实现是因为字典类型的远程调用客户端中,不需要实现该方法,因此尽早抛出异常,用户可自行修改。
*
* @param queryParam 查询参数。
* @return 应答结果对象,包含主对象集合
* @return 分页数据集合对象。如MyQueryParam参数的分页属性为空则不会执行分页操作只是基于MyPageData对象返回数据结果
*/
default ResponseResult<List<D>> listBy(MyQueryParam queryParam) {
default ResponseResult<MyPageData<V>> listBy(MyQueryParam queryParam) {
throw new UnsupportedOperationException();
}
@@ -89,7 +87,7 @@ public interface BaseClient<D, K> {
* @param queryParam 查询参数。
* @return 应答结果对象,包含主对象集合。
*/
default ResponseResult<D> getBy(MyQueryParam queryParam) {
default ResponseResult<V> getBy(MyQueryParam queryParam) {
throw new UnsupportedOperationException();
}
@@ -98,9 +96,9 @@ public interface BaseClient<D, K> {
* 缺省实现是因为字典类型的远程调用客户端中,不需要实现该方法,因此尽早抛出异常,用户可自行修改。
*
* @param queryParam 查询参数。
* @return 应答结果对象,包含主对象集合
* @return 分页数据集合对象。如MyQueryParam参数的分页属性为空则不会执行分页操作只是基于MyPageData对象返回数据结果
*/
default ResponseResult<List<Map<String, Object>>> listMapBy(MyQueryParam queryParam) {
default ResponseResult<MyPageData<Map<String, Object>>> listMapBy(MyQueryParam queryParam) {
throw new UnsupportedOperationException();
}
@@ -130,9 +128,9 @@ public interface BaseClient<D, K> {
* 根据主键Id及其列表数据(not in list)进行过滤,返回给定的数据。返回的对象数据中,仅仅包含实体对象自己的数据,以及配置的字典关联数据。
*
* @param queryParam 查询参数。
* @return 应答结果对象,包含数据列表,以及整个符合条件的数据总量(分页之前)
* @return 应答结果对象,包含分页查询数据列表。
*/
default ResponseResult<Tuple2<List<D>, K>> listByNotInList(MyQueryParam queryParam) {
default ResponseResult<MyPageData<V>> listByNotInList(MyQueryParam queryParam) {
throw new UnsupportedOperationException();
}
}

View File

@@ -1,10 +1,7 @@
package com.orange.demo.common.core.base.client;
import com.orange.demo.common.core.constant.ErrorCodeEnum;
import com.orange.demo.common.core.object.MyAggregationParam;
import com.orange.demo.common.core.object.MyQueryParam;
import com.orange.demo.common.core.object.ResponseResult;
import com.orange.demo.common.core.object.Tuple2;
import com.orange.demo.common.core.object.*;
import feign.hystrix.FallbackFactory;
import lombok.extern.slf4j.Slf4j;
@@ -13,23 +10,24 @@ import java.util.*;
/**
* FeignClient 熔断降级处理对象。
*
* @param <D> 实体对象类型。
* @param <D> 主DomainDto域数据对象类型。
* @param <V> 主DomainVo域数据对象类型。
* @param <K> 主键类型。
* @param <T> Feign客户端对象类型。
* @author Jerry
* @date 2020-08-08
*/
@Slf4j
public abstract class BaseFallbackFactory<D, K, T extends BaseClient<D, K>>
implements FallbackFactory<T>, BaseClient<D, K> {
public abstract class BaseFallbackFactory<D, V, K, T extends BaseClient<D, V, K>>
implements FallbackFactory<T>, BaseClient<D, V, K> {
@Override
public ResponseResult<List<D>> listByIds(Set<K> idSet, Boolean withDict) {
public ResponseResult<List<V>> listByIds(Set<K> idSet, Boolean withDict) {
return ResponseResult.error(ErrorCodeEnum.RPC_DATA_ACCESS_FAILED);
}
@Override
public ResponseResult<D> getById(K id, Boolean withDict) {
public ResponseResult<V> getById(K id, Boolean withDict) {
return ResponseResult.error(ErrorCodeEnum.RPC_DATA_ACCESS_FAILED);
}
@@ -54,17 +52,17 @@ public abstract class BaseFallbackFactory<D, K, T extends BaseClient<D, K>>
}
@Override
public ResponseResult<List<D>> listBy(MyQueryParam queryParam) {
public ResponseResult<MyPageData<V>> listBy(MyQueryParam queryParam) {
return ResponseResult.error(ErrorCodeEnum.RPC_DATA_ACCESS_FAILED);
}
@Override
public ResponseResult<D> getBy(MyQueryParam queryParam) {
public ResponseResult<V> getBy(MyQueryParam queryParam) {
return ResponseResult.error(ErrorCodeEnum.RPC_DATA_ACCESS_FAILED);
}
@Override
public ResponseResult<List<Map<String, Object>>> listMapBy(MyQueryParam queryParam) {
public ResponseResult<MyPageData<Map<String, Object>>> listMapBy(MyQueryParam queryParam) {
return ResponseResult.error(ErrorCodeEnum.RPC_DATA_ACCESS_FAILED);
}
@@ -79,7 +77,7 @@ public abstract class BaseFallbackFactory<D, K, T extends BaseClient<D, K>>
}
@Override
public ResponseResult<Tuple2<List<D>, K>> listByNotInList(MyQueryParam queryParam) {
public ResponseResult<MyPageData<V>> listByNotInList(MyQueryParam queryParam) {
return ResponseResult.error(ErrorCodeEnum.RPC_DATA_ACCESS_FAILED);
}
}

View File

@@ -11,6 +11,7 @@ import com.orange.demo.common.core.exception.RemoteDataBuildException;
import com.orange.demo.common.core.object.*;
import com.orange.demo.common.core.util.MyCommonUtil;
import com.orange.demo.common.core.util.MyModelUtil;
import com.github.pagehelper.Page;
import com.github.pagehelper.page.PageMethod;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
@@ -30,22 +31,22 @@ import java.util.stream.Collectors;
* 控制器Controller的基类。
*
* @param <M> 主Model实体对象类型。
* @param <D> 主DomainDto域对象类型。
* @param <V> 主Model的DomainVO域对象类型。
* @param <K> 主键类型。
* @author Jerry
* @date 2020-08-08
*/
@Slf4j
public abstract class BaseController<M, D, K> {
public abstract class BaseController<M, V, K> {
/**
* 当前Service关联的主Model实体对象的Class。
*/
protected Class<M> modelClass;
/**
* 当前Service关联的主DomainDto域对象的Class。
* 当前Service关联的主model的VO对象的Class。
*/
protected Class<D> domainDtoClass;
protected Class<V> domainVoClass;
/**
* 当前Service关联的主Model对象主键字段名称。
*/
@@ -56,7 +57,7 @@ public abstract class BaseController<M, D, K> {
*
* @return 子类中注入的BaseService类。
*/
protected abstract BaseService<M, D, K> service();
protected abstract BaseService<M, K> service();
/**
* 构造函数。
@@ -64,7 +65,7 @@ public abstract class BaseController<M, D, K> {
@SuppressWarnings("unchecked")
public BaseController() {
modelClass = (Class<M>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
domainDtoClass = (Class<D>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[1];
domainVoClass = (Class<V>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[1];
Field[] fields = ReflectUtil.getFields(modelClass);
for (Field field : fields) {
if (null != field.getAnnotation(Id.class)) {
@@ -83,21 +84,21 @@ public abstract class BaseController<M, D, K> {
* @return 应答结果对象,包含主对象集合。
* @throws RemoteDataBuildException buildRelationForDataList会抛出该异常。
*/
public ResponseResult<List<D>> baseListByIds(
Set<K> filterIds, Boolean withDict, BaseModelMapper<D, M> modelMapper) {
public ResponseResult<List<V>> baseListByIds(
Set<K> filterIds, Boolean withDict, BaseModelMapper<V, M> modelMapper) {
if (MyCommonUtil.existBlankArgument(filterIds, withDict)) {
return ResponseResult.error(ErrorCodeEnum.ARGUMENT_NULL_EXIST);
}
List<M> resultList = service().getInList(idFieldName, filterIds);
List<D> resultDtoList = null;
List<V> resultVoList = null;
if (CollectionUtils.isEmpty(resultList)) {
return ResponseResult.success(resultDtoList);
return ResponseResult.success(resultVoList);
}
if (Boolean.TRUE.equals(withDict)) {
service().buildRelationForDataList(resultList, MyRelationParam.dictOnly(), null);
}
resultDtoList = convertToDomainList(resultList, modelMapper);
return ResponseResult.success(resultDtoList);
resultVoList = convertToVoList(resultList, modelMapper);
return ResponseResult.success(resultVoList);
}
/**
@@ -109,20 +110,20 @@ public abstract class BaseController<M, D, K> {
* @return 应答结果对象,包含主对象数据。
* @throws RemoteDataBuildException buildRelationForData会抛出此异常。
*/
public ResponseResult<D> baseGetById(K id, Boolean withDict, BaseModelMapper<D, M> modelMapper) {
public ResponseResult<V> baseGetById(K id, Boolean withDict, BaseModelMapper<V, M> modelMapper) {
if (MyCommonUtil.existBlankArgument(id, withDict)) {
return ResponseResult.error(ErrorCodeEnum.ARGUMENT_NULL_EXIST);
}
M resultObject = service().getById(id);
D resultDtoObject = null;
V resultVoObject = null;
if (resultObject == null) {
return ResponseResult.success(resultDtoObject);
return ResponseResult.success(resultVoObject);
}
if (Boolean.TRUE.equals(withDict)) {
service().buildRelationForData(resultObject, MyRelationParam.dictOnly(), null);
}
resultDtoObject = this.convertToDomain(resultObject, modelMapper);
return ResponseResult.success(resultDtoObject);
resultVoObject = this.convertToVo(resultObject, modelMapper);
return ResponseResult.success(resultVoObject);
}
/**
@@ -150,13 +151,11 @@ public abstract class BaseController<M, D, K> {
/**
* 删除符合过滤条件的数据。
*
* @param filter 过滤对象。
* @param modelMapper 对象映射函数对象。如果为空则使用MyModelUtil中的缺省转换函数。
* @param filter 过滤对象。
* @return 删除数量。
*/
public ResponseResult<Integer> baseDeleteBy(
D filter, BaseModelMapper<D, M> modelMapper) throws Exception {
return ResponseResult.success(service().removeBy(convertToModel(filter, modelMapper)));
public ResponseResult<Integer> baseDeleteBy(M filter) throws Exception {
return ResponseResult.success(service().removeBy(filter));
}
/**
@@ -165,10 +164,10 @@ public abstract class BaseController<M, D, K> {
*
* @param queryParam 查询参数。
* @param modelMapper 对象映射函数对象。如果为空则使用MyModelUtil中的缺省转换函数。
* @return 应答结果对象,包含符合查询过滤条件的对象结果
* @return 分页数据集合对象。如MyQueryParam参数的分页属性为空则不会执行分页操作只是基于MyPageData对象返回数据结果。
* @throws RemoteDataBuildException buildRelationForDataList会抛出此异常。
*/
public ResponseResult<List<D>> baseListBy(MyQueryParam queryParam, BaseModelMapper<D, M> modelMapper) {
public ResponseResult<MyPageData<V>> baseListBy(MyQueryParam queryParam, BaseModelMapper<V, M> modelMapper) {
if (CollectionUtils.isNotEmpty(queryParam.getSelectFieldList())) {
for (String fieldName : queryParam.getSelectFieldList()) {
String columnName = MyModelUtil.mapToColumnName(fieldName, modelClass);
@@ -179,22 +178,29 @@ public abstract class BaseController<M, D, K> {
}
}
}
M filter = queryParam.getFilterDto(modelClass);
String whereClause = MyWhereCriteria.makeCriteriaString(queryParam.getCriteriaList(), modelClass);
String orderBy = MyOrderParam.buildOrderBy(queryParam.getOrderParam(), modelClass);
MyPageParam pageParam = queryParam.getPageParam();
if (pageParam != null) {
PageMethod.startPage(pageParam.getPageNum(), pageParam.getPageSize());
}
List<M> resultList = service().getListByCondition(queryParam.getSelectFieldList(), whereClause, orderBy);
List<D> resultDtoList = null;
List<M> resultList = service().getListByCondition(
queryParam.getSelectFieldList(), filter, whereClause, orderBy);
if (CollectionUtils.isEmpty(resultList)) {
return ResponseResult.success(resultDtoList);
return ResponseResult.success(MyPageData.emptyPageData());
}
long totalCount;
if (resultList instanceof Page) {
totalCount = ((Page<M>) resultList).getTotal();
} else {
totalCount = resultList.size();
}
if (queryParam.getWithDict()) {
service().buildRelationForDataList(resultList, MyRelationParam.dictOnly(), null);
}
resultDtoList = convertToDomainList(resultList, modelMapper);
return ResponseResult.success(resultDtoList);
List<V> resultVoList = convertToVoList(resultList, modelMapper);
return ResponseResult.success(new MyPageData<>(resultVoList, totalCount));
}
/**
@@ -203,17 +209,17 @@ public abstract class BaseController<M, D, K> {
*
* @param queryParam 查询参数。
* @param modelMapper 对象映射函数对象。如果为空则使用MyModelUtil中的缺省转换函数。
* @return 应答结果对象,包含符合查询过滤条件的对象结果
* @return 分页数据集合对象。如MyQueryParam参数的分页属性为空则不会执行分页操作只是基于MyPageData对象返回数据结果。
*/
public ResponseResult<List<Map<String, Object>>> baseListMapBy(
MyQueryParam queryParam, BaseModelMapper<D, M> modelMapper) {
ResponseResult<List<D>> result = this.baseListBy(queryParam, modelMapper);
public ResponseResult<MyPageData<Map<String, Object>>> baseListMapBy(
MyQueryParam queryParam, BaseModelMapper<V, M> modelMapper) {
ResponseResult<MyPageData<V>> result = this.baseListBy(queryParam, modelMapper);
if (!result.isSuccess()) {
return ResponseResult.errorFrom(result);
}
List<Map<String, Object>> resultMapList =
result.getData().stream().map(BeanUtil::beanToMap).collect(Collectors.toList());
return ResponseResult.success(resultMapList);
result.getData().getDataList().stream().map(BeanUtil::beanToMap).collect(Collectors.toList());
return ResponseResult.success(new MyPageData<>(resultMapList, result.getData().getTotalCount()));
}
/**
@@ -223,13 +229,13 @@ public abstract class BaseController<M, D, K> {
* @param modelMapper 对象映射函数对象。如果为空则使用MyModelUtil中的缺省转换函数。
* @return 应答结果对象,包含符合查询过滤条件的单条实体对象。
*/
public ResponseResult<D> baseGetBy(MyQueryParam queryParam, BaseModelMapper<D, M> modelMapper) {
ResponseResult<List<D>> result = baseListBy(queryParam, modelMapper);
public ResponseResult<V> baseGetBy(MyQueryParam queryParam, BaseModelMapper<V, M> modelMapper) {
ResponseResult<MyPageData<V>> result = baseListBy(queryParam, modelMapper);
if (!result.isSuccess()) {
return ResponseResult.errorFrom(result);
}
List<D> dataList = result.getData();
D data = null;
List<V> dataList = result.getData().getDataList();
V data = null;
if (CollectionUtils.isNotEmpty(dataList)) {
data = dataList.get(0);
}
@@ -310,77 +316,39 @@ public abstract class BaseController<M, D, K> {
}
/**
* 将查询对象中过滤域对象转换为实体对象。以便作为Service的参数进行数据过滤
* 如果Model存在该实体的ModelMapper就用该ModelMapper转换否则使用缺省的基于字段反射的copy。
*
* @param filterDto 过滤域对象。
* @param modelMapper 从Dto对象到实体对象的映射对象。
* @return 转换后的实体过滤对象。
*/
public M convertFilter(D filterDto, BaseModelMapper<D, M> modelMapper) {
M filter = null;
if (filterDto != null) {
if (modelMapper != null) {
filter = modelMapper.toModel(filterDto);
} else {
filter = MyModelUtil.copyTo(filterDto, modelClass);
}
}
return filter;
}
/**
* 将Model实体对象的集合转换为DomainDto域对象的集合。
* 将Model实体对象的集合转换为DomainVO域对象的集合
* 如果Model存在该实体的ModelMapper就用该ModelMapper转换否则使用缺省的基于字段反射的copy。
*
* @param modelList 实体对象列表。
* @param modelMapper 从实体对象到Dto对象的映射对象。
* @return 转换后的Dto域对象列表。
* @param modelMapper 从实体对象到VO对象的映射对象。
* @return 转换后的VO域对象列表。
*/
private List<D> convertToDomainList(List<M> modelList, BaseModelMapper<D, M> modelMapper) {
List<D> resultDtoList;
private List<V> convertToVoList(List<M> modelList, BaseModelMapper<V, M> modelMapper) {
List<V> resultVoList;
if (modelMapper != null) {
resultDtoList = modelMapper.fromModelList(modelList);
resultVoList = modelMapper.fromModelList(modelList);
} else {
resultDtoList = MyModelUtil.copyCollectionTo(modelList, domainDtoClass);
resultVoList = MyModelUtil.copyCollectionTo(modelList, domainVoClass);
}
return resultDtoList;
return resultVoList;
}
/**
* 将Model实体对象转换为DomainDto域对象。
* 将Model实体对象转换为DomainVO域对象。
* 如果Model存在该实体的ModelMapper就用该ModelMapper转换否则使用缺省的基于字段反射的copy。
*
* @param model 实体对象。
* @param modelMapper 从实体对象到Dto对象的映射对象。
* @return 转换后的Dto域对象。
* @param modelMapper 从实体对象到VO对象的映射对象。
* @return 转换后的VO域对象。
*/
private D convertToDomain(M model, BaseModelMapper<D, M> modelMapper) {
D resultDto;
private V convertToVo(M model, BaseModelMapper<V, M> modelMapper) {
V resultVo;
if (modelMapper != null) {
resultDto = modelMapper.fromModel(model);
resultVo = modelMapper.fromModel(model);
} else {
resultDto = MyModelUtil.copyTo(model, domainDtoClass);
resultVo = MyModelUtil.copyTo(model, domainVoClass);
}
return resultDto;
}
/**
* 将Dto对象转换为Model实体对象。
* 如果Model存在该实体的ModelMapper就用该ModelMapper转换否则使用缺省的基于字段反射的copy。
*
* @param dto Dto对象。
* @param modelMapper 从实体对象到Dto对象的映射对象。
* @return 转换后的Dto域对象。
*/
private M convertToModel(D dto, BaseModelMapper<D, M> modelMapper) {
M result;
if (modelMapper != null) {
result = modelMapper.toModel(dto);
} else {
result = MyModelUtil.copyTo(dto, modelClass);
}
return result;
return resultVo;
}
private VerifyAggregationInfo verifyAndParseAggregationParam(MyAggregationParam param) {

View File

@@ -14,13 +14,12 @@ import java.util.List;
* 目前仅支持基于主键字段的缓存查找,其他条件的查找仍然从数据源获取。
*
* @param <M> Model实体对象的类型。
* @param <D> Model对应的DomainDto域对象类型。
* @param <K> Model对象主键的类型。
* @author Jerry
* @date 2020-08-08
*/
@Slf4j
public abstract class BaseDictService<M, D, K> extends BaseService<M, D, K> {
public abstract class BaseDictService<M, K> extends BaseService<M, K> {
/**
* 缓存池对象。
@@ -126,7 +125,7 @@ public abstract class BaseDictService<M, D, K> extends BaseService<M, D, K> {
@SuppressWarnings("unchecked")
public <T> boolean existUniqueKeyList(String inFilterField, Set<T> inFilterValues) {
if (CollectionUtils.isEmpty(inFilterValues)) {
return false;
return true;
}
if (inFilterField.equals(this.idFieldName)) {
List<M> dataList = dictionaryCache.getInList((Set<K>) inFilterValues);

View File

@@ -25,6 +25,7 @@ import javax.persistence.Column;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Transient;
import java.lang.reflect.Modifier;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
@@ -37,22 +38,17 @@ import static java.util.stream.Collectors.*;
* 所有Service的基类。
*
* @param <M> Model对象的类型。
* @param <D> Model对应的Dto对象类型。
* @param <K> Model对象主键的类型。
* @author Jerry
* @date 2020-08-08
*/
@Slf4j
public abstract class BaseService<M, D, K> {
public abstract class BaseService<M, K> {
/**
* 当前Service关联的主Model实体对象的Class。
*/
protected Class<M> modelClass;
/**
* 当前Service关联的主DomainDto域对象的Class。
*/
protected Class<D> domainDtoClass;
/**
* 当前Service关联的主Model对象的实际表名称。
*/
@@ -142,7 +138,6 @@ public abstract class BaseService<M, D, K> {
@SuppressWarnings("unchecked")
public BaseService() {
modelClass = (Class<M>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
domainDtoClass = (Class<D>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[1];
this.tableName = modelClass.getAnnotation(Table.class).name();
Field[] fields = ReflectUtil.getFields(modelClass);
for (Field field : fields) {
@@ -239,7 +234,7 @@ public abstract class BaseService<M, D, K> {
}
Example e = new Example(modelClass);
e.createCriteria().andEqualTo(fieldName, fieldValue);
return mapper().selectByExample(e).size() == 1;
return mapper().selectCountByExample(e) == 1;
}
/**
@@ -325,7 +320,7 @@ public abstract class BaseService<M, D, K> {
*/
public boolean existAllPrimaryKeys(Set<K> idSet) {
if (CollectionUtils.isEmpty(idSet)) {
return false;
return true;
}
return this.existUniqueKeyList(idFieldName, idSet);
}
@@ -339,7 +334,7 @@ public abstract class BaseService<M, D, K> {
*/
public <T> boolean existUniqueKeyList(String inFilterField, Set<T> inFilterValues) {
if (CollectionUtils.isEmpty(inFilterValues)) {
return false;
return true;
}
Example e = this.makeDefaultInListExample(inFilterField, inFilterValues, null);
if (deletedFlagFieldName != null) {
@@ -513,20 +508,21 @@ public abstract class BaseService<M, D, K> {
int modifiers = field.getModifiers();
// transient类型的字段不能作为查询条件
int transientMask = 128;
if ((modifiers & transientMask) == 0) {
if (field.getName().equals(deletedFlagFieldName)) {
c.andEqualTo(deletedFlagFieldName, GlobalDeletedFlag.NORMAL);
} else {
ReflectUtil.setAccessible(field);
try {
Object o = field.get(filter);
if (o != null) {
c.andEqualTo(field.getName(), field.get(filter));
}
} catch (IllegalAccessException ex) {
log.error("Failed to call reflection code of BaseService.getListByFilter.", ex);
throw new MyRuntimeException(ex);
if ((modifiers & transientMask) != 0 || Modifier.isStatic(modifiers)) {
return;
}
if (field.getName().equals(deletedFlagFieldName)) {
c.andEqualTo(deletedFlagFieldName, GlobalDeletedFlag.NORMAL);
} else {
ReflectUtil.setAccessible(field);
try {
Object o = field.get(filter);
if (o != null) {
c.andEqualTo(field.getName(), field.get(filter));
}
} catch (IllegalAccessException ex) {
log.error("Failed to call reflection code of BaseService.getListByFilter.", ex);
throw new MyRuntimeException(ex);
}
}
}
@@ -556,10 +552,14 @@ public abstract class BaseService<M, D, K> {
*/
public List<M> getListByParentId(String parentIdFieldName, K parentId) {
Example e = new Example(modelClass);
Example.Criteria c = e.createCriteria();
if (parentId != null) {
e.createCriteria().andEqualTo(parentIdFieldName, parentId);
c.andEqualTo(parentIdFieldName, parentId);
} else {
e.createCriteria().andIsNull(parentIdFieldName);
c.andIsNull(parentIdFieldName);
}
if (deletedFlagFieldName != null) {
c.andEqualTo(deletedFlagFieldName, GlobalDeletedFlag.NORMAL);
}
return mapper().selectByExample(e);
}
@@ -583,12 +583,14 @@ public abstract class BaseService<M, D, K> {
* 根据指定的显示字段列表、过滤条件字符串和排序字符串,返回查询结果。(基本是内部框架使用,不建议外部接口直接使用)。
*
* @param selectList 选择的Java字段列表。如果为空表示返回全部字段。
* @param filter 过滤对象。
* @param whereClause SQL常量形式的条件从句。
* @param orderBy SQL常量形式排序字段列表逗号分隔。
* @return 查询结果。
*/
public List<M> getListByCondition(List<String> selectList, String whereClause, String orderBy) {
public List<M> getListByCondition(List<String> selectList, M filter, String whereClause, String orderBy) {
Example e = new Example(modelClass);
Example.Criteria c = null;
if (CollectionUtils.isNotEmpty(selectList)) {
String[] selectFields = new String[selectList.size()];
selectList.toArray(selectFields);
@@ -597,8 +599,20 @@ public abstract class BaseService<M, D, K> {
if (StringUtils.isNotBlank(orderBy)) {
e.setOrderByClause(orderBy);
}
if (filter != null) {
c = e.createCriteria();
Field[] fields = ReflectUtil.getFields(modelClass);
for (Field field : fields) {
if (field.getAnnotation(Transient.class) == null) {
this.assembleCriteriaByFilter(filter, field, c);
}
}
}
if (StringUtils.isNotBlank(whereClause)) {
e.createCriteria().andCondition(whereClause);
if (c == null) {
c = e.createCriteria();
}
c.andCondition(whereClause);
}
return mapper().selectByExample(e);
}
@@ -811,9 +825,9 @@ public abstract class BaseService<M, D, K> {
whereCriteria.setCriteria(
relationStruct.relationOneToOne.slaveIdField(), MyWhereCriteria.OPERATOR_IN, masterIdSet);
queryParam.addCriteriaList(whereCriteria);
ResponseResult<List<Object>> result = relationStruct.remoteClient.listBy(queryParam);
ResponseResult<MyPageData<Object>> result = relationStruct.remoteClient.listBy(queryParam);
if (result.isSuccess()) {
List<Object> relationList = result.getData();
List<Object> relationList = result.getData().getDataList();
MyModelUtil.makeOneToOneRelation(
modelClass, resultList, relationList, relationStruct.relationField.getName());
} else {
@@ -889,10 +903,10 @@ public abstract class BaseService<M, D, K> {
whereCriteria.setCriteria(
relationStruct.relationDict.slaveIdField(), MyWhereCriteria.OPERATOR_IN, masterIdSet);
queryParam.addCriteriaList(whereCriteria);
ResponseResult<List<Object>> result = relationStruct.remoteClient.listBy(queryParam);
ResponseResult<MyPageData<Object>> result = relationStruct.remoteClient.listBy(queryParam);
// 成功或者没有数据
if (result.isSuccess()) {
relationList = result.getData();
relationList = result.getData().getDataList();
} else {
logErrorOrThrowException(result.getErrorMessage());
}
@@ -1135,7 +1149,7 @@ public abstract class BaseService<M, D, K> {
if (CollectionUtils.isEmpty(masterIdSet)) {
continue;
}
BaseService<Object, Object, Object> relationService = relationStruct.localService;
BaseService<Object, Object> relationService = relationStruct.localService;
List<Object> relationList =
relationService.getInList(relationStruct.relationOneToOne.slaveIdField(), masterIdSet);
MyModelUtil.makeOneToOneRelation(
@@ -1144,8 +1158,8 @@ public abstract class BaseService<M, D, K> {
if (withDict && relationStruct.relationOneToOne.loadSlaveDict()
&& CollectionUtils.isNotEmpty(relationList)) {
@SuppressWarnings("unchecked")
BaseService<Object, Object, Object> proxyTarget =
(BaseService<Object, Object, Object>) AopTargetUtil.getTarget(relationService);
BaseService<Object, Object> proxyTarget =
(BaseService<Object, Object>) AopTargetUtil.getTarget(relationService);
// 关联常量字典
proxyTarget.buildConstDictForDataList(relationList);
// 关联本地字典。
@@ -1170,14 +1184,14 @@ public abstract class BaseService<M, D, K> {
for (LocalRelationStruct relationStruct : this.localRelationOneToOneStructList) {
Object id = ReflectUtil.getFieldValue(dataObject, relationStruct.masterIdField);
if (id != null) {
BaseService<Object, Object, Object> relationService = relationStruct.localService;
BaseService<Object, Object> relationService = relationStruct.localService;
Object relationObject = relationService.getById(id);
ReflectUtil.setFieldValue(dataObject, relationStruct.relationField, relationObject);
// 仅仅当需要加载从表字典关联时,才去加载。
if (withDict && relationStruct.relationOneToOne.loadSlaveDict() && relationObject != null) {
@SuppressWarnings("unchecked")
BaseService<Object, Object, Object> proxyTarget =
(BaseService<Object, Object, Object>) AopTargetUtil.getTarget(relationService);
BaseService<Object, Object> proxyTarget =
(BaseService<Object, Object>) AopTargetUtil.getTarget(relationService);
// 关联常量字典
proxyTarget.buildConstDictForData(relationObject);
// 关联本地字典。
@@ -1573,7 +1587,7 @@ public abstract class BaseService<M, D, K> {
ReflectUtil.getField(modelClass, relationDict.equalOneToOneRelationField());
}
Object client = ApplicationContextHolder.getBean(relationDict.slaveClientClass());
relationStruct.remoteClient = (BaseClient<Object, Object>) client;
relationStruct.remoteClient = (BaseClient<Object, Object, Object>) client;
remoteRelationDictStructList.add(relationStruct);
}
}
@@ -1590,7 +1604,7 @@ public abstract class BaseService<M, D, K> {
relationStruct.masterIdField = ReflectUtil.getField(modelClass, relationOneToOne.masterIdField());
relationStruct.relationOneToOne = relationOneToOne;
Object client = ApplicationContextHolder.getBean(relationOneToOne.slaveClientClass());
relationStruct.remoteClient = (BaseClient<Object, Object>) client;
relationStruct.remoteClient = (BaseClient<Object, Object, Object>) client;
remoteRelationOneToOneStructList.add(relationStruct);
}
}
@@ -1608,7 +1622,7 @@ public abstract class BaseService<M, D, K> {
relationStruct.masterIdField = ReflectUtil.getField(modelClass, relationOneToManyAggregation.masterIdField());
relationStruct.relationOneToManyAggregation = relationOneToManyAggregation;
Object client = ApplicationContextHolder.getBean(relationOneToManyAggregation.slaveClientClass());
relationStruct.remoteClient = (BaseClient<Object, Object>) client;
relationStruct.remoteClient = (BaseClient<Object, Object, Object>) client;
remoteRelationOneToManyAggrStructList.add(relationStruct);
return;
}
@@ -1624,7 +1638,7 @@ public abstract class BaseService<M, D, K> {
modelClass, relationManyToManyAggregation.masterIdField());
relationStruct.relationManyToManyAggregation = relationManyToManyAggregation;
Object client = ApplicationContextHolder.getBean(relationManyToManyAggregation.slaveClientClass());
relationStruct.remoteClient = (BaseClient<Object, Object>) client;
relationStruct.remoteClient = (BaseClient<Object, Object, Object>) client;
remoteRelationManyToManyAggrStructList.add(relationStruct);
}
}
@@ -1856,7 +1870,7 @@ public abstract class BaseService<M, D, K> {
List<String> slaveSelectList = new LinkedList<>();
slaveSelectList.add(relation.slaveIdField());
queryParam.setSelectFieldList(slaveSelectList);
ResponseResult<List<Map<String, Object>>> result = relationStruct.remoteClient.listMapBy(queryParam);
ResponseResult<MyPageData<Map<String, Object>>> result = relationStruct.remoteClient.listMapBy(queryParam);
if (!result.isSuccess()) {
this.logErrorOrThrowException(result.getErrorMessage());
return;
@@ -1865,7 +1879,8 @@ public abstract class BaseService<M, D, K> {
// 并计算最终聚合结果。
List<Object> slaveList = null;
if (result.getData() != null) {
slaveList = result.getData().stream().map(m -> m.get(relation.slaveIdField())).collect(toList());
slaveList = result.getData().getDataList()
.stream().map(m -> m.get(relation.slaveIdField())).collect(toList());
}
if (CollectionUtils.isNotEmpty(slaveList)) {
// 中间表的最终过滤条件是从表返回的id列表将作为关联表slaveIdColumn的inlist-filter
@@ -2101,7 +2116,7 @@ public abstract class BaseService<M, D, K> {
static class LocalRelationStruct extends RelationStruct {
private Field equalOneToOneRelationField;
private BaseService<Object, Object, Object> localService;
private BaseService<Object, Object> localService;
private BaseDaoMapper<Object> manyToManyMapper;
private Map<Object, String> dictMap;
private RelationDict relationDict;
@@ -2113,7 +2128,7 @@ public abstract class BaseService<M, D, K> {
static class RemoteRelationStruct extends RelationStruct {
private Field equalOneToOneRelationField;
private BaseClient<Object, Object> remoteClient;
private BaseClient<Object, Object, Object> remoteClient;
private RelationDict relationDict;
private RelationOneToOne relationOneToOne;
private RelationOneToManyAggregation relationOneToManyAggregation;

View File

@@ -35,6 +35,9 @@ public enum ErrorCodeEnum {
INVALID_USERNAME_PASSWORD("用户名或密码错误,请重试!"),
INVALID_ACCESS_TOKEN("无效的用户访问令牌!"),
INVALID_USER_STATUS("用户状态错误,请刷新后重试!"),
INVALID_TENANT_CODE("指定的租户编码并不存在,请刷新后重试!"),
INVALID_TENANT_STATUS("当前租户为不可用状态,请刷新后重试!"),
INVALID_USER_TENANT("当前用户并不属于当前租户,请刷新后重试!"),
HAS_CHILDREN_DATA("数据验证失败,子数据存在,请刷新后重试!"),
DATA_VALIDATED_FAILED("数据验证失败,请核对!"),

View File

@@ -1,7 +1,10 @@
package com.orange.demo.common.core.object;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.LinkedList;
import java.util.List;
/**
@@ -11,6 +14,8 @@ import java.util.List;
* @date 2020-08-08
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class MyPageData<T> {
/**
* 数据列表。
@@ -20,4 +25,12 @@ public class MyPageData<T> {
* 数据总数量。
*/
private Long totalCount;
/**
* 为了保持前端的数据格式兼容性,在没有数据的时候,需要返回空分页对象。
* @return 空分页对象。
*/
public static <T> MyPageData<T> emptyPageData() {
return new MyPageData<>(new LinkedList<>(), 0L);
}
}

View File

@@ -91,7 +91,7 @@ public class MyQueryParam {
if (filterMap == null) {
return null;
}
return BeanUtil.mapToBean(this.filterMap, filterClazz, true);
return BeanUtil.toBeanIgnoreError(this.filterMap, filterClazz);
}
/**

View File

@@ -19,6 +19,7 @@ import javax.persistence.Column;
import javax.persistence.Table;
import javax.persistence.Transient;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
@@ -427,6 +428,9 @@ public class MyModelUtil {
Function<R, Object> thatIdGetterFunc,
String thisRelationField,
boolean orderByThatList) {
if (CollectionUtils.isEmpty(thisModelList)) {
return;
}
Field thisTargetField = ReflectUtil.getField(thisClazz, thisRelationField);
boolean isMap = thisTargetField.getType().equals(Map.class);
if (orderByThatList) {
@@ -476,12 +480,12 @@ public class MyModelUtil {
Example.Criteria c = e.createCriteria();
Field[] fields = ReflectUtil.getFields(modelClass);
for (Field field : fields) {
if (field.getAnnotation(Transient.class) != null) {
continue;
}
int modifiers = field.getModifiers();
// transient类型的字段不能作为查询条件
if ((modifiers & 128) == 0) {
if (field.getAnnotation(Transient.class) == null) {
int modifiers = field.getModifiers();
// transient类型的字段不能作为查询条件
if ((modifiers & 128) != 0 || Modifier.isStatic(modifiers)) {
continue;
}
ReflectUtil.setAccessible(field);
try {
Object o = field.get(filterModel);

View File

@@ -2,11 +2,11 @@ package com.orange.demo.common.core.util;
import cn.jimmyshi.beanquery.BeanQuery;
import com.alibaba.fastjson.JSONObject;
import com.orange.demo.common.core.object.MyPageData;
import com.github.pagehelper.Page;
import com.orange.demo.common.core.base.mapper.BaseModelMapper;
import com.orange.demo.common.core.object.Tuple2;
import org.apache.commons.collections4.CollectionUtils;
import com.orange.demo.common.core.base.mapper.BaseModelMapper;
import com.orange.demo.common.core.object.MyPageData;
import com.orange.demo.common.core.object.Tuple2;
import java.util.List;
@@ -75,18 +75,17 @@ public class MyPageUtil {
* 用户构建带有分页信息的数据列表。
*
* @param dataList 实体对象数据列表。
* @param modelMapper 实体对象到Dto对象的数据映射器。
* @param <D> Dto对象类型。
* @param modelMapper 实体对象到DomainVO对象的数据映射器。
* @param <D> DomainVO对象类型。
* @param <T> 实体对象类型。
* @return 返回分页数据对象。
*/
public static <D, T> MyPageData<D> makeResponseData(List<T> dataList, BaseModelMapper<D, T> modelMapper) {
MyPageData<D> pageData = new MyPageData<>();
long totalCount = 0L;
if (CollectionUtils.isEmpty(dataList)) {
// 这里需要构建分页数据对象,统一前端数据格式
return pageData;
return MyPageData.emptyPageData();
}
long totalCount = 0L;
if (dataList instanceof Page) {
totalCount = ((Page<T>) dataList).getTotal();
}

View File

@@ -63,10 +63,12 @@ public class SessionCacheHelper {
/**
* 清除当前session的所有缓存数据。
*
* @param sessionId 当前会话的SessionId。
*/
public void removeAllSessionCache() {
public void removeAllSessionCache(String sessionId) {
for (RedissonCacheConfig.CacheEnum c : RedissonCacheConfig.CacheEnum.values()) {
cacheManager.getCache(c.name()).clear();
cacheManager.getCache(c.name()).evict(sessionId);
}
}
}