mirror of
https://github.com/continew-org/continew-starter.git
synced 2025-09-09 04:59:21 +08:00
refactor(extension/crud): 重构查询树列表功能,增加重载方法,支持构建单个根节点或者多个根节点的树结构
This commit is contained in:
@@ -60,15 +60,26 @@ public interface CrudService<L, D, Q, C> {
|
|||||||
List<L> list(@Valid Q query, @Valid SortQuery sortQuery);
|
List<L> list(@Valid Q query, @Valid SortQuery sortQuery);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询树列表
|
* 查询树列表(多个根节点)
|
||||||
*
|
*
|
||||||
* @param query 查询条件
|
* @param query 查询条件
|
||||||
* @param sortQuery 排序查询条件
|
* @param sortQuery 排序查询条件
|
||||||
* @param isSimple 是否为简单树结构(不包含基本树结构之外的扩展字段,简单树(下拉列表)使用全局配置结构,复杂树(表格)使用 @DictField 局部配置)
|
* @param isSimple 是否为简单树结构(不包含基本树结构之外的扩展字段,简单树(下拉列表)使用全局配置结构,复杂树(表格)使用 @TreeField 局部配置)
|
||||||
* @return 树列表信息
|
* @return 树列表信息
|
||||||
*/
|
*/
|
||||||
List<Tree<Long>> tree(@Valid Q query, @Valid SortQuery sortQuery, boolean isSimple);
|
List<Tree<Long>> tree(@Valid Q query, @Valid SortQuery sortQuery, boolean isSimple);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询树列表
|
||||||
|
*
|
||||||
|
* @param query 查询条件
|
||||||
|
* @param sortQuery 排序查询条件
|
||||||
|
* @param isSimple 是否为简单树结构(不包含基本树结构之外的扩展字段,简单树(下拉列表)使用全局配置结构,复杂树(表格)使用 @TreeField 局部配置)
|
||||||
|
* @param isSingleRoot 是否为单个根节点
|
||||||
|
* @return 树列表信息
|
||||||
|
*/
|
||||||
|
List<Tree<Long>> tree(@Valid Q query, @Valid SortQuery sortQuery, boolean isSimple, boolean isSingleRoot);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询详情
|
* 查询详情
|
||||||
*
|
*
|
||||||
|
@@ -27,15 +27,20 @@ import cn.hutool.core.util.ReflectUtil;
|
|||||||
import cn.hutool.extra.spring.SpringUtil;
|
import cn.hutool.extra.spring.SpringUtil;
|
||||||
import com.mybatisflex.core.paginate.Page;
|
import com.mybatisflex.core.paginate.Page;
|
||||||
import com.mybatisflex.core.query.QueryWrapper;
|
import com.mybatisflex.core.query.QueryWrapper;
|
||||||
|
import jakarta.el.MethodNotFoundException;
|
||||||
import jakarta.servlet.http.HttpServletResponse;
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
import org.springframework.data.domain.Sort;
|
import org.springframework.data.domain.Sort;
|
||||||
|
import org.springframework.lang.NonNull;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
import top.continew.starter.core.constant.StringConstants;
|
import top.continew.starter.core.constant.StringConstants;
|
||||||
|
import top.continew.starter.core.exception.BusinessException;
|
||||||
import top.continew.starter.core.util.ReflectUtils;
|
import top.continew.starter.core.util.ReflectUtils;
|
||||||
|
import top.continew.starter.core.util.TreeBuildUtils;
|
||||||
import top.continew.starter.core.util.validation.ValidationUtils;
|
import top.continew.starter.core.util.validation.ValidationUtils;
|
||||||
import top.continew.starter.data.base.BaseMapper;
|
import top.continew.starter.data.base.BaseMapper;
|
||||||
import top.continew.starter.data.service.impl.ServiceImpl;
|
import top.continew.starter.data.service.impl.ServiceImpl;
|
||||||
import top.continew.starter.data.util.QueryWrapperHelper;
|
import top.continew.starter.data.util.QueryWrapperHelper;
|
||||||
|
import top.continew.starter.excel.util.ExcelUtils;
|
||||||
import top.continew.starter.extension.crud.annotation.TreeField;
|
import top.continew.starter.extension.crud.annotation.TreeField;
|
||||||
import top.continew.starter.extension.crud.autoconfigure.CrudProperties;
|
import top.continew.starter.extension.crud.autoconfigure.CrudProperties;
|
||||||
import top.continew.starter.extension.crud.autoconfigure.CrudTreeProperties;
|
import top.continew.starter.extension.crud.autoconfigure.CrudTreeProperties;
|
||||||
@@ -44,12 +49,14 @@ import top.continew.starter.extension.crud.model.query.PageQuery;
|
|||||||
import top.continew.starter.extension.crud.model.query.SortQuery;
|
import top.continew.starter.extension.crud.model.query.SortQuery;
|
||||||
import top.continew.starter.extension.crud.model.resp.LabelValueResp;
|
import top.continew.starter.extension.crud.model.resp.LabelValueResp;
|
||||||
import top.continew.starter.extension.crud.model.resp.PageResp;
|
import top.continew.starter.extension.crud.model.resp.PageResp;
|
||||||
import top.continew.starter.excel.util.ExcelUtils;
|
|
||||||
|
|
||||||
|
import java.lang.invoke.MethodHandleProxies;
|
||||||
|
import java.lang.invoke.MethodHandles;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.util.ArrayList;
|
import java.lang.reflect.Method;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* CRUD 业务实现基类
|
* CRUD 业务实现基类
|
||||||
@@ -89,9 +96,14 @@ public class CrudServiceImpl<M extends BaseMapper<T>, T extends BaseIdDO, L, D,
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<Tree<Long>> tree(Q query, SortQuery sortQuery, boolean isSimple) {
|
public List<Tree<Long>> tree(Q query, SortQuery sortQuery, boolean isSimple) {
|
||||||
|
return this.tree(query, sortQuery, true, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Tree<Long>> tree(Q query, SortQuery sortQuery, boolean isSimple, boolean isSingleRoot) {
|
||||||
List<L> list = this.list(query, sortQuery);
|
List<L> list = this.list(query, sortQuery);
|
||||||
if (CollUtil.isEmpty(list)) {
|
if (CollUtil.isEmpty(list)) {
|
||||||
return new ArrayList<>(0);
|
return CollUtil.newArrayList();
|
||||||
}
|
}
|
||||||
CrudProperties crudProperties = SpringUtil.getBean(CrudProperties.class);
|
CrudProperties crudProperties = SpringUtil.getBean(CrudProperties.class);
|
||||||
CrudTreeProperties treeProperties = crudProperties.getTree();
|
CrudTreeProperties treeProperties = crudProperties.getTree();
|
||||||
@@ -106,21 +118,88 @@ public class CrudServiceImpl<M extends BaseMapper<T>, T extends BaseIdDO, L, D,
|
|||||||
treeNodeConfig = treeProperties.genTreeNodeConfig(treeField);
|
treeNodeConfig = treeProperties.genTreeNodeConfig(treeField);
|
||||||
rootId = treeField.rootId();
|
rootId = treeField.rootId();
|
||||||
}
|
}
|
||||||
// 构建树
|
if (isSingleRoot) {
|
||||||
return TreeUtil.build(list, rootId, treeNodeConfig, (node, tree) -> {
|
// 构建单根节点树
|
||||||
tree.setId(ReflectUtil.invoke(node, CharSequenceUtil.genGetter(treeField.value())));
|
return TreeUtil.build(list, rootId, treeNodeConfig, (node,
|
||||||
tree.setParentId(ReflectUtil.invoke(node, CharSequenceUtil.genGetter(treeField.parentIdKey())));
|
tree) -> buildTreeField(isSimple, node, tree, treeField));
|
||||||
tree.setName(ReflectUtil.invoke(node, CharSequenceUtil.genGetter(treeField.nameKey())));
|
} else {
|
||||||
tree.setWeight(ReflectUtil.invoke(node, CharSequenceUtil.genGetter(treeField.weightKey())));
|
Function<L, Long> getId = createMethodReference(listClass, CharSequenceUtil.genGetter(treeField.value()));
|
||||||
// 如果构建简单树结构,则不包含扩展字段
|
Function<L, Long> getParentId = createMethodReference(listClass, CharSequenceUtil.genGetter(treeField
|
||||||
if (!isSimple) {
|
.parentIdKey()));
|
||||||
List<Field> fieldList = ReflectUtils.getNonStaticFields(listClass);
|
// 构建多根节点树
|
||||||
fieldList.removeIf(f -> CharSequenceUtil.equalsAnyIgnoreCase(f.getName(), treeField.value(), treeField
|
return TreeBuildUtils.buildMultiRoot(list, getId, getParentId, treeNodeConfig, (node,
|
||||||
.parentIdKey(), treeField.nameKey(), treeField.weightKey(), treeField.childrenKey()));
|
tree) -> buildTreeField(isSimple, node, tree, treeField));
|
||||||
fieldList.forEach(f -> tree.putExtra(f.getName(), ReflectUtil.invoke(node, CharSequenceUtil.genGetter(f
|
}
|
||||||
.getName()))));
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 构建树字段
|
||||||
|
*
|
||||||
|
* @param isSimple 是否简单树结构
|
||||||
|
* @param node 节点
|
||||||
|
* @param tree 树
|
||||||
|
* @param treeField 树字段
|
||||||
|
*/
|
||||||
|
private void buildTreeField(boolean isSimple, L node, Tree<Long> tree, TreeField treeField) {
|
||||||
|
tree.setId(ReflectUtil.invoke(node, CharSequenceUtil.genGetter(treeField.value())));
|
||||||
|
tree.setParentId(ReflectUtil.invoke(node, CharSequenceUtil.genGetter(treeField.parentIdKey())));
|
||||||
|
tree.setName(ReflectUtil.invoke(node, CharSequenceUtil.genGetter(treeField.nameKey())));
|
||||||
|
tree.setWeight(ReflectUtil.invoke(node, CharSequenceUtil.genGetter(treeField.weightKey())));
|
||||||
|
// 如果构建简单树结构,则不包含扩展字段
|
||||||
|
if (!isSimple) {
|
||||||
|
List<Field> fieldList = ReflectUtils.getNonStaticFields(listClass);
|
||||||
|
fieldList.removeIf(f -> CharSequenceUtil.equalsAnyIgnoreCase(f.getName(), treeField.value(), treeField
|
||||||
|
.parentIdKey(), treeField.nameKey(), treeField.weightKey(), treeField.childrenKey()));
|
||||||
|
fieldList.forEach(f -> tree.putExtra(f.getName(), ReflectUtil.invoke(node, CharSequenceUtil.genGetter(f
|
||||||
|
.getName()))));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过反射创建方法引用,支持在父类中查找方法
|
||||||
|
*
|
||||||
|
* @param clazz 实体类类型
|
||||||
|
* @param methodName 方法名
|
||||||
|
* @param <T> 实体类类型
|
||||||
|
* @param <K> 返回值类型
|
||||||
|
* @return Function<T, K> 方法引用
|
||||||
|
* @throws IllegalArgumentException 如果参数不合法
|
||||||
|
* @throws MethodNotFoundException 如果在类层次结构中找不到指定方法
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public static <T, K> Function<T, K> createMethodReference(@NonNull Class<T> clazz, @NonNull String methodName) {
|
||||||
|
Method method = getMethod(clazz, methodName);
|
||||||
|
try {
|
||||||
|
// 设置访问权限并返回方法引用
|
||||||
|
method.setAccessible(true);
|
||||||
|
return MethodHandleProxies.asInterfaceInstance(Function.class, MethodHandles.lookup().unreflect(method));
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new BusinessException("创建方法引用失败: " + clazz.getName() + "." + methodName, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取方法(包括父类)
|
||||||
|
*
|
||||||
|
* @param clazz 实体类
|
||||||
|
* @param methodName 方法名
|
||||||
|
* @param <T> 实体类
|
||||||
|
* @return 方法
|
||||||
|
*/
|
||||||
|
private static <T> Method getMethod(Class<T> clazz, String methodName) {
|
||||||
|
Class<?> currentClass = clazz;
|
||||||
|
Method method = null;
|
||||||
|
// 查找方法(包括父类)
|
||||||
|
while (currentClass != null) {
|
||||||
|
try {
|
||||||
|
method = currentClass.getDeclaredMethod(methodName);
|
||||||
|
break;
|
||||||
|
} catch (NoSuchMethodException e) {
|
||||||
|
// 继续查找父类
|
||||||
|
currentClass = currentClass.getSuperclass();
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
return method;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@@ -22,6 +22,7 @@ import cn.hutool.core.collection.CollUtil;
|
|||||||
import cn.hutool.core.convert.Convert;
|
import cn.hutool.core.convert.Convert;
|
||||||
import cn.hutool.core.lang.tree.Tree;
|
import cn.hutool.core.lang.tree.Tree;
|
||||||
import cn.hutool.core.lang.tree.TreeNodeConfig;
|
import cn.hutool.core.lang.tree.TreeNodeConfig;
|
||||||
|
import cn.hutool.core.lang.tree.TreeUtil;
|
||||||
import cn.hutool.core.map.MapUtil;
|
import cn.hutool.core.map.MapUtil;
|
||||||
import cn.hutool.core.text.CharSequenceUtil;
|
import cn.hutool.core.text.CharSequenceUtil;
|
||||||
import cn.hutool.core.util.ReflectUtil;
|
import cn.hutool.core.util.ReflectUtil;
|
||||||
@@ -29,10 +30,13 @@ import cn.hutool.extra.spring.SpringUtil;
|
|||||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import jakarta.el.MethodNotFoundException;
|
||||||
import jakarta.servlet.http.HttpServletResponse;
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
import org.springframework.data.domain.Sort;
|
import org.springframework.data.domain.Sort;
|
||||||
|
import org.springframework.lang.NonNull;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
import top.continew.starter.core.constant.StringConstants;
|
import top.continew.starter.core.constant.StringConstants;
|
||||||
|
import top.continew.starter.core.exception.BusinessException;
|
||||||
import top.continew.starter.core.util.ClassUtils;
|
import top.continew.starter.core.util.ClassUtils;
|
||||||
import top.continew.starter.core.util.ReflectUtils;
|
import top.continew.starter.core.util.ReflectUtils;
|
||||||
import top.continew.starter.core.util.TreeBuildUtils;
|
import top.continew.starter.core.util.TreeBuildUtils;
|
||||||
@@ -97,58 +101,111 @@ public class CrudServiceImpl<M extends BaseMapper<T>, T extends BaseIdDO, L, D,
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<Tree<Long>> tree(Q query, SortQuery sortQuery, boolean isSimple) {
|
public List<Tree<Long>> tree(Q query, SortQuery sortQuery, boolean isSimple) {
|
||||||
|
return this.tree(query, sortQuery, true, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Tree<Long>> tree(Q query, SortQuery sortQuery, boolean isSimple, boolean isSingleRoot) {
|
||||||
List<L> list = this.list(query, sortQuery);
|
List<L> list = this.list(query, sortQuery);
|
||||||
if (CollUtil.isEmpty(list)) {
|
if (CollUtil.isEmpty(list)) {
|
||||||
return new ArrayList<>(0);
|
return CollUtil.newArrayList();
|
||||||
}
|
}
|
||||||
CrudProperties crudProperties = SpringUtil.getBean(CrudProperties.class);
|
CrudProperties crudProperties = SpringUtil.getBean(CrudProperties.class);
|
||||||
CrudTreeProperties treeProperties = crudProperties.getTree();
|
CrudTreeProperties treeProperties = crudProperties.getTree();
|
||||||
TreeField treeField = listClass.getDeclaredAnnotation(TreeField.class);
|
TreeField treeField = listClass.getDeclaredAnnotation(TreeField.class);
|
||||||
|
TreeNodeConfig treeNodeConfig;
|
||||||
|
Long rootId;
|
||||||
// 简单树(下拉列表)使用全局配置结构,复杂树(表格)使用局部配置
|
// 简单树(下拉列表)使用全局配置结构,复杂树(表格)使用局部配置
|
||||||
TreeNodeConfig treeNodeConfig = isSimple
|
if (isSimple) {
|
||||||
? treeProperties.genTreeNodeConfig()
|
treeNodeConfig = treeProperties.genTreeNodeConfig();
|
||||||
: treeProperties.genTreeNodeConfig(treeField);
|
rootId = treeProperties.getRootId();
|
||||||
String valueGetter = CharSequenceUtil.genGetter(treeField.value());
|
} else {
|
||||||
String parentIdKeyGetter = CharSequenceUtil.genGetter(treeField.parentIdKey());
|
treeNodeConfig = treeProperties.genTreeNodeConfig(treeField);
|
||||||
Function<L, Long> getId = createMethodReference(listClass, valueGetter);
|
rootId = treeField.rootId();
|
||||||
Function<L, Long> getParentId = createMethodReference(listClass, parentIdKeyGetter);
|
}
|
||||||
// 构建树
|
if (isSingleRoot) {
|
||||||
return TreeBuildUtils.buildMultiRoot(list, getId, getParentId, treeNodeConfig, (node, tree) -> {
|
// 构建单根节点树
|
||||||
tree.setId(ReflectUtil.invoke(node, valueGetter));
|
return TreeUtil.build(list, rootId, treeNodeConfig, (node,
|
||||||
tree.setParentId(ReflectUtil.invoke(node, parentIdKeyGetter));
|
tree) -> buildTreeField(isSimple, node, tree, treeField));
|
||||||
tree.setName(ReflectUtil.invoke(node, CharSequenceUtil.genGetter(treeField.nameKey())));
|
} else {
|
||||||
tree.setWeight(ReflectUtil.invoke(node, CharSequenceUtil.genGetter(treeField.weightKey())));
|
Function<L, Long> getId = createMethodReference(listClass, CharSequenceUtil.genGetter(treeField.value()));
|
||||||
// 如果构建简单树结构,则不包含扩展字段
|
Function<L, Long> getParentId = createMethodReference(listClass, CharSequenceUtil.genGetter(treeField
|
||||||
if (!isSimple) {
|
.parentIdKey()));
|
||||||
List<Field> fieldList = ReflectUtils.getNonStaticFields(listClass);
|
// 构建多根节点树
|
||||||
fieldList.removeIf(f -> CharSequenceUtil.equalsAnyIgnoreCase(f.getName(), treeField.value(), treeField
|
return TreeBuildUtils.buildMultiRoot(list, getId, getParentId, treeNodeConfig, (node,
|
||||||
.parentIdKey(), treeField.nameKey(), treeField.weightKey(), treeField.childrenKey()));
|
tree) -> buildTreeField(isSimple, node, tree, treeField));
|
||||||
fieldList.forEach(f -> tree.putExtra(f.getName(), ReflectUtil.invoke(node, CharSequenceUtil.genGetter(f
|
}
|
||||||
.getName()))));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 通过反射创建方法引用
|
* 构建树字段
|
||||||
|
*
|
||||||
|
* @param isSimple 是否简单树结构
|
||||||
|
* @param node 节点
|
||||||
|
* @param tree 树
|
||||||
|
* @param treeField 树字段
|
||||||
|
*/
|
||||||
|
private void buildTreeField(boolean isSimple, L node, Tree<Long> tree, TreeField treeField) {
|
||||||
|
tree.setId(ReflectUtil.invoke(node, CharSequenceUtil.genGetter(treeField.value())));
|
||||||
|
tree.setParentId(ReflectUtil.invoke(node, CharSequenceUtil.genGetter(treeField.parentIdKey())));
|
||||||
|
tree.setName(ReflectUtil.invoke(node, CharSequenceUtil.genGetter(treeField.nameKey())));
|
||||||
|
tree.setWeight(ReflectUtil.invoke(node, CharSequenceUtil.genGetter(treeField.weightKey())));
|
||||||
|
// 如果构建简单树结构,则不包含扩展字段
|
||||||
|
if (!isSimple) {
|
||||||
|
List<Field> fieldList = ReflectUtils.getNonStaticFields(listClass);
|
||||||
|
fieldList.removeIf(f -> CharSequenceUtil.equalsAnyIgnoreCase(f.getName(), treeField.value(), treeField
|
||||||
|
.parentIdKey(), treeField.nameKey(), treeField.weightKey(), treeField.childrenKey()));
|
||||||
|
fieldList.forEach(f -> tree.putExtra(f.getName(), ReflectUtil.invoke(node, CharSequenceUtil.genGetter(f
|
||||||
|
.getName()))));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过反射创建方法引用,支持在父类中查找方法
|
||||||
*
|
*
|
||||||
* @param clazz 实体类类型
|
* @param clazz 实体类类型
|
||||||
* @param methodName 方法名
|
* @param methodName 方法名
|
||||||
* @param <T> 实体类类型
|
* @param <T> 实体类类型
|
||||||
* @param <K> 返回值类型
|
* @param <K> 返回值类型
|
||||||
* @return Function<T, K> 方法引用
|
* @return Function<T, K> 方法引用
|
||||||
|
* @throws IllegalArgumentException 如果参数不合法
|
||||||
|
* @throws MethodNotFoundException 如果在类层次结构中找不到指定方法
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public static <T, K> Function<T, K> createMethodReference(Class<T> clazz, String methodName) {
|
public static <T, K> Function<T, K> createMethodReference(@NonNull Class<T> clazz, @NonNull String methodName) {
|
||||||
try {
|
try {
|
||||||
Method method = clazz.getDeclaredMethod(methodName);
|
Method method = getMethod(clazz, methodName);
|
||||||
method.setAccessible(true);
|
method.setAccessible(true);
|
||||||
return MethodHandleProxies.asInterfaceInstance(Function.class, MethodHandles.lookup().unreflect(method));
|
return MethodHandleProxies.asInterfaceInstance(Function.class, MethodHandles.lookup().unreflect(method));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new RuntimeException("Failed to create method reference for " + methodName, e);
|
throw new BusinessException("创建方法引用失败:" + clazz.getName() + StringConstants.DOT + methodName, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取方法(包括父类)
|
||||||
|
*
|
||||||
|
* @param clazz 实体类
|
||||||
|
* @param methodName 方法名
|
||||||
|
* @param <T> 实体类
|
||||||
|
* @return 方法
|
||||||
|
*/
|
||||||
|
private static <T> Method getMethod(Class<T> clazz, String methodName) {
|
||||||
|
Class<?> currentClass = clazz;
|
||||||
|
Method method = null;
|
||||||
|
// 查找方法(包括父类)
|
||||||
|
while (currentClass != null) {
|
||||||
|
try {
|
||||||
|
method = currentClass.getDeclaredMethod(methodName);
|
||||||
|
break;
|
||||||
|
} catch (NoSuchMethodException e) {
|
||||||
|
// 继续查找父类
|
||||||
|
currentClass = currentClass.getSuperclass();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return method;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public D get(Long id) {
|
public D get(Long id) {
|
||||||
T entity = super.getById(id, false);
|
T entity = super.getById(id, false);
|
||||||
|
Reference in New Issue
Block a user