|
|
@@ -7,9 +7,12 @@ import java.lang.reflect.Method;
|
|
|
import java.lang.reflect.Modifier;
|
|
|
import java.util.ArrayList;
|
|
|
import java.util.Arrays;
|
|
|
+import java.util.Collection;
|
|
|
import java.util.List;
|
|
|
|
|
|
import org.apache.ibatis.ognl.OgnlRuntime;
|
|
|
+import org.slf4j.Logger;
|
|
|
+import org.slf4j.LoggerFactory;
|
|
|
import org.springframework.core.annotation.AnnotationUtils;
|
|
|
import org.springframework.util.ObjectUtils;
|
|
|
|
|
|
@@ -19,10 +22,12 @@ import com.baomidou.mybatisplus.core.toolkit.StringUtils;
|
|
|
import com.github.yulichang.wrapper.MPJLambdaWrapper;
|
|
|
|
|
|
/**
|
|
|
- * @Description 拼接查询条件工具类
|
|
|
+ * Lambda 表达式查询条件拼接工具类 支持通过注解自动构建查询条件
|
|
|
*/
|
|
|
public class QueryLambdaUtil {
|
|
|
|
|
|
+ private static final Logger log = LoggerFactory.getLogger(QueryLambdaUtil.class);
|
|
|
+
|
|
|
/**
|
|
|
* 得到父类的对象
|
|
|
*
|
|
|
@@ -48,23 +53,36 @@ public class QueryLambdaUtil {
|
|
|
/**
|
|
|
* 拼接查询条件,将附加的值放在map里面查询
|
|
|
*
|
|
|
- * @param obj 数据实体
|
|
|
- * @return void 返回参数说明
|
|
|
- * @exception/throws
|
|
|
+ * @param queryWrapper 查询包装器
|
|
|
+ * @param objs 数据实体对象(可以是多个,最后一个可以是 QueryMap)
|
|
|
+ * @return MPJLambdaWrapper 查询条件包装器
|
|
|
*/
|
|
|
public static <T> MPJLambdaWrapper<T> convertQuery(MPJLambdaWrapper<T> queryWrapper, Object... objs) {
|
|
|
- //
|
|
|
QueryMap param = new QueryMap();
|
|
|
if (ArrayUtils.isNotEmpty(objs)) {
|
|
|
Object lastObj = objs[objs.length - 1];
|
|
|
if (lastObj instanceof QueryMap) {
|
|
|
param = (QueryMap) lastObj;
|
|
|
}
|
|
|
- // 判断最后一个是否是QueryMap
|
|
|
+ }
|
|
|
+
|
|
|
+ // 获取查询目标实体类 T(通过反射从 queryWrapper 获取)
|
|
|
+ Class<T> targetEntityClass = getTargetEntityClass(queryWrapper);
|
|
|
+ if (targetEntityClass == null) {
|
|
|
+ log.warn("Cannot get target entity class from queryWrapper, query may fail");
|
|
|
+ return queryWrapper;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 判断最后一个是否是QueryMap,如果不是 QueryMap 则处理所有对象
|
|
|
+ if (ArrayUtils.isNotEmpty(objs)) {
|
|
|
for (Object obj : objs) {
|
|
|
- Class<?> clazz = obj.getClass();
|
|
|
+ // 跳过 QueryMap 对象
|
|
|
+ if (obj instanceof QueryMap) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ Class<?> objClass = obj.getClass();
|
|
|
try {
|
|
|
- for (Field field : reflectForField(clazz)) {
|
|
|
+ for (Field field : reflectForField(objClass)) {
|
|
|
TableField tableField = AnnotationUtils.getAnnotation(field, TableField.class);
|
|
|
// 字段没有TableField这个注解和有这个主机上false的
|
|
|
|
|
|
@@ -74,11 +92,18 @@ public class QueryLambdaUtil {
|
|
|
// 获取属性名
|
|
|
String name = field.getName();
|
|
|
// 声明属性描述对象
|
|
|
- Method method = getMethod(clazz, name);
|
|
|
+ Method method = getMethod(objClass, name);
|
|
|
if (method == null) {
|
|
|
continue;
|
|
|
}
|
|
|
- Object fieldValue = method.invoke(obj);
|
|
|
+ Object fieldValue;
|
|
|
+ try {
|
|
|
+ fieldValue = method.invoke(obj);
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.debug("Failed to invoke getter method for field: {} in class: {}", name,
|
|
|
+ objClass.getName(), e);
|
|
|
+ continue;
|
|
|
+ }
|
|
|
String fieldName;
|
|
|
if (tableField == null) {
|
|
|
fieldName = StringUtils.camelToUnderline(name);
|
|
|
@@ -89,7 +114,8 @@ public class QueryLambdaUtil {
|
|
|
QueryWapper queryWapperAnnotation = AnnotationUtils.getAnnotation(field, QueryWapper.class);
|
|
|
if (ObjectUtils.isEmpty(queryWapperAnnotation)) {
|
|
|
if (!ObjectUtils.isEmpty(fieldValue)) {
|
|
|
- queryWrapper.eq(getSFunction(clazz, fieldName), fieldValue);
|
|
|
+ // 使用目标实体类 T 创建 Lambda 表达式,而不是传入对象的类
|
|
|
+ queryWrapper.eq(getSFunction(targetEntityClass, fieldName), fieldValue);
|
|
|
}
|
|
|
} else {
|
|
|
// 获取枚举
|
|
|
@@ -99,67 +125,69 @@ public class QueryLambdaUtil {
|
|
|
switch (queryWapperEnum) {
|
|
|
case NE:
|
|
|
if (!ObjectUtils.isEmpty(fieldValue)) {
|
|
|
- queryWrapper.ne(getSFunction(clazz, fieldName), fieldValue);
|
|
|
+ queryWrapper.ne(getSFunction(targetEntityClass, fieldName), fieldValue);
|
|
|
}
|
|
|
break;
|
|
|
// 这里需要,修改为集合
|
|
|
case IN:
|
|
|
- if (fieldValue != null && fieldValue.toString().contains(",")) {
|
|
|
- List<String> result = Arrays.asList(fieldValue.toString().split(","));
|
|
|
- if (!ObjectUtils.isEmpty(fieldValue)) {
|
|
|
- queryWrapper.in(getSFunction(clazz, fieldName), result);
|
|
|
+ if (!ObjectUtils.isEmpty(fieldValue)) {
|
|
|
+ if (fieldValue instanceof Collection) {
|
|
|
+ queryWrapper.in(getSFunction(targetEntityClass, fieldName), (Collection<?>) fieldValue);
|
|
|
+ } else if (fieldValue.toString().contains(",")) {
|
|
|
+ List<String> result = Arrays.asList(fieldValue.toString().split(","));
|
|
|
+ queryWrapper.in(getSFunction(targetEntityClass, fieldName), result);
|
|
|
+ } else {
|
|
|
+ queryWrapper.in(getSFunction(targetEntityClass, fieldName), fieldValue);
|
|
|
}
|
|
|
}
|
|
|
break;
|
|
|
case GT:
|
|
|
if (!ObjectUtils.isEmpty(fieldValue)) {
|
|
|
- if (!ObjectUtils.isEmpty(fieldValue)) {
|
|
|
- queryWrapper.gt(getSFunction(clazz, fieldName), fieldValue);
|
|
|
- }
|
|
|
+ queryWrapper.gt(getSFunction(targetEntityClass, fieldName), fieldValue);
|
|
|
}
|
|
|
break;
|
|
|
case EQ:
|
|
|
if (!ObjectUtils.isEmpty(fieldValue)) {
|
|
|
- queryWrapper.eq(getSFunction(clazz, fieldName), fieldValue);
|
|
|
+ queryWrapper.eq(getSFunction(targetEntityClass, fieldName), fieldValue);
|
|
|
}
|
|
|
break;
|
|
|
case GE:
|
|
|
if (!ObjectUtils.isEmpty(fieldValue)) {
|
|
|
- queryWrapper.ge(getSFunction(clazz, fieldName), fieldValue);
|
|
|
+ queryWrapper.ge(getSFunction(targetEntityClass, fieldName), fieldValue);
|
|
|
}
|
|
|
break;
|
|
|
case LT:
|
|
|
if (!ObjectUtils.isEmpty(fieldValue)) {
|
|
|
- queryWrapper.lt(getSFunction(clazz, fieldName), fieldValue);
|
|
|
+ queryWrapper.lt(getSFunction(targetEntityClass, fieldName), fieldValue);
|
|
|
}
|
|
|
break;
|
|
|
case LE:
|
|
|
if (!ObjectUtils.isEmpty(fieldValue)) {
|
|
|
- queryWrapper.le(getSFunction(clazz, fieldName), fieldValue);
|
|
|
+ queryWrapper.le(getSFunction(targetEntityClass, fieldName), fieldValue);
|
|
|
}
|
|
|
break;
|
|
|
case LIKE:
|
|
|
if (!ObjectUtils.isEmpty(fieldValue)) {
|
|
|
- queryWrapper.like(getSFunction(clazz, fieldName), fieldValue);
|
|
|
+ queryWrapper.like(getSFunction(targetEntityClass, fieldName), fieldValue);
|
|
|
}
|
|
|
break;
|
|
|
case NOT_LIKE:
|
|
|
if (!ObjectUtils.isEmpty(fieldValue)) {
|
|
|
- queryWrapper.notLike(getSFunction(clazz, fieldName), fieldValue);
|
|
|
+ queryWrapper.notLike(getSFunction(targetEntityClass, fieldName), fieldValue);
|
|
|
}
|
|
|
break;
|
|
|
case LIKE_LEFT:
|
|
|
if (!ObjectUtils.isEmpty(fieldValue)) {
|
|
|
- queryWrapper.likeLeft(getSFunction(clazz, fieldName), fieldValue);
|
|
|
+ queryWrapper.likeLeft(getSFunction(targetEntityClass, fieldName), fieldValue);
|
|
|
}
|
|
|
break;
|
|
|
case LIKE_RIGHT:
|
|
|
if (!ObjectUtils.isEmpty(fieldValue)) {
|
|
|
- queryWrapper.likeRight(getSFunction(clazz, fieldName), fieldValue);
|
|
|
+ queryWrapper.likeRight(getSFunction(targetEntityClass, fieldName), fieldValue);
|
|
|
}
|
|
|
break;
|
|
|
case DESC:
|
|
|
- queryWrapper.orderByDesc(fieldName);
|
|
|
+ queryWrapper.orderByDesc(getSFunction(targetEntityClass, fieldName));
|
|
|
break;
|
|
|
case AND:
|
|
|
// 支持通过attribute指定多字段AND连接(格式:{"field1", "field2"})
|
|
|
@@ -167,13 +195,17 @@ public class QueryLambdaUtil {
|
|
|
if (ArrayUtils.isNotEmpty(andFields)) {
|
|
|
for (String andField : andFields) {
|
|
|
// 反射获取关联字段的值
|
|
|
- Method andMethod = getMethod(clazz, andField);
|
|
|
+ Method andMethod = getMethod(objClass, andField);
|
|
|
if (andMethod != null) {
|
|
|
- Object andValue = andMethod.invoke(obj);
|
|
|
- if (!ObjectUtils.isEmpty(andValue)) {
|
|
|
- // 转换为数据库字段名
|
|
|
- String dbAndField = getDbFieldName(clazz, andField, tableField);
|
|
|
- queryWrapper.eq(getSFunction(clazz, dbAndField), andValue);
|
|
|
+ try {
|
|
|
+ Object andValue = andMethod.invoke(obj);
|
|
|
+ if (!ObjectUtils.isEmpty(andValue)) {
|
|
|
+ // 转换为数据库字段名
|
|
|
+ String dbAndField = getDbFieldName(objClass, andField, tableField);
|
|
|
+ queryWrapper.eq(getSFunction(targetEntityClass, dbAndField), andValue);
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.warn("Failed to invoke method for AND field: {}", andField, e);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
@@ -183,18 +215,35 @@ public class QueryLambdaUtil {
|
|
|
case BETWEEN:
|
|
|
// 通过attribute指定开始/结束字段(格式:{"startField", "endField"})
|
|
|
String[] betweenFields = queryWapperAnnotation.attribute();
|
|
|
- if (betweenFields.length == 2) {
|
|
|
- // 获取开始值
|
|
|
- Method startMethod = getMethod(clazz, betweenFields[0]);
|
|
|
- Object startVal = startMethod != null ? startMethod.invoke(obj) : null;
|
|
|
- // 获取结束值
|
|
|
- Method endMethod = getMethod(clazz, betweenFields[1]);
|
|
|
- Object endVal = endMethod != null ? endMethod.invoke(obj) : null;
|
|
|
- // 两个值都存在时才添加BETWEEN条件
|
|
|
- if (!ObjectUtils.isEmpty(startVal) && !ObjectUtils.isEmpty(endVal)) {
|
|
|
- queryWrapper.between(getSFunction(clazz, fieldName), startVal, endVal);
|
|
|
+ if (betweenFields == null || betweenFields.length < 2) {
|
|
|
+ log.warn("BETWEEN query requires 2 attributes, but got: {}",
|
|
|
+ betweenFields == null ? 0 : betweenFields.length);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ // 获取开始值
|
|
|
+ Method startMethod = getMethod(objClass, betweenFields[0]);
|
|
|
+ Object startVal = null;
|
|
|
+ if (startMethod != null) {
|
|
|
+ try {
|
|
|
+ startVal = startMethod.invoke(obj);
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.warn("Failed to invoke method for startField: {}", betweenFields[0], e);
|
|
|
}
|
|
|
}
|
|
|
+ // 获取结束值
|
|
|
+ Method endMethod = getMethod(objClass, betweenFields[1]);
|
|
|
+ Object endVal = null;
|
|
|
+ if (endMethod != null) {
|
|
|
+ try {
|
|
|
+ endVal = endMethod.invoke(obj);
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.warn("Failed to invoke method for endField: {}", betweenFields[1], e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 两个值都存在时才添加BETWEEN条件
|
|
|
+ if (!ObjectUtils.isEmpty(startVal) && !ObjectUtils.isEmpty(endVal)) {
|
|
|
+ queryWrapper.between(getSFunction(targetEntityClass, fieldName), startVal, endVal);
|
|
|
+ }
|
|
|
break;
|
|
|
|
|
|
case GROUP_BY:
|
|
|
@@ -202,8 +251,8 @@ public class QueryLambdaUtil {
|
|
|
String[] groupFields = queryWapperAnnotation.attribute();
|
|
|
if (ArrayUtils.isNotEmpty(groupFields)) {
|
|
|
for (String groupField : groupFields) {
|
|
|
- String dbGroupField = getDbFieldName(clazz, groupField, tableField);
|
|
|
- queryWrapper.groupBy(getSFunction(clazz, dbGroupField));
|
|
|
+ String dbGroupField = getDbFieldName(objClass, groupField, tableField);
|
|
|
+ queryWrapper.groupBy(getSFunction(targetEntityClass, dbGroupField));
|
|
|
}
|
|
|
}
|
|
|
break;
|
|
|
@@ -218,12 +267,12 @@ public class QueryLambdaUtil {
|
|
|
|
|
|
case IS_NOT_NULL:
|
|
|
// 字段非空判断(无需值,直接添加条件)
|
|
|
- queryWrapper.isNotNull(getSFunction(clazz, fieldName));
|
|
|
+ queryWrapper.isNotNull(getSFunction(targetEntityClass, fieldName));
|
|
|
break;
|
|
|
|
|
|
case IS_NULL:
|
|
|
// 字段为空判断(无需值,直接添加条件)
|
|
|
- queryWrapper.isNull(getSFunction(clazz, fieldName));
|
|
|
+ queryWrapper.isNull(getSFunction(targetEntityClass, fieldName));
|
|
|
break;
|
|
|
|
|
|
case NOT:
|
|
|
@@ -231,18 +280,23 @@ public class QueryLambdaUtil {
|
|
|
String[] notFields = queryWapperAnnotation.attribute();
|
|
|
if (ArrayUtils.isNotEmpty(notFields)) {
|
|
|
String notField = notFields[0];
|
|
|
- Method notMethod = getMethod(clazz, notField);
|
|
|
+ Method notMethod = getMethod(objClass, notField);
|
|
|
if (notMethod != null) {
|
|
|
- Object notValue = notMethod.invoke(obj);
|
|
|
- if (!ObjectUtils.isEmpty(notValue)) {
|
|
|
- String dbNotField = getDbFieldName(clazz, notField, tableField);
|
|
|
- queryWrapper.not(i -> {
|
|
|
- try {
|
|
|
- i.eq(getSFunction(clazz, dbNotField), notValue);
|
|
|
- } catch (Exception e) {
|
|
|
- e.printStackTrace();
|
|
|
- }
|
|
|
- });
|
|
|
+ try {
|
|
|
+ Object notValue = notMethod.invoke(obj);
|
|
|
+ if (!ObjectUtils.isEmpty(notValue)) {
|
|
|
+ String dbNotField = getDbFieldName(objClass, notField, tableField);
|
|
|
+ queryWrapper.not(i -> {
|
|
|
+ try {
|
|
|
+ i.eq(getSFunction(targetEntityClass, dbNotField), notValue);
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("Failed to build NOT condition for field: {}",
|
|
|
+ dbNotField, e);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.warn("Failed to invoke method for NOT field: {}", notField, e);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
@@ -251,28 +305,55 @@ public class QueryLambdaUtil {
|
|
|
case NOT_BETWEEN:
|
|
|
// 同BETWEEN,取反逻辑
|
|
|
String[] notBetweenFields = queryWapperAnnotation.attribute();
|
|
|
- if (notBetweenFields.length == 2) {
|
|
|
- Method notStartMethod = getMethod(clazz, notBetweenFields[0]);
|
|
|
- Object notStartVal = notStartMethod != null ? notStartMethod.invoke(obj) : null;
|
|
|
- Method notEndMethod = getMethod(clazz, notBetweenFields[1]);
|
|
|
- Object notEndVal = notEndMethod != null ? notEndMethod.invoke(obj) : null;
|
|
|
- if (!ObjectUtils.isEmpty(notStartVal) && !ObjectUtils.isEmpty(notEndVal)) {
|
|
|
- queryWrapper.notBetween(getSFunction(clazz, fieldName), notStartVal,
|
|
|
- notEndVal);
|
|
|
+ if (notBetweenFields == null || notBetweenFields.length < 2) {
|
|
|
+ log.warn("NOT_BETWEEN query requires 2 attributes, but got: {}",
|
|
|
+ notBetweenFields == null ? 0 : notBetweenFields.length);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ Method notStartMethod = getMethod(objClass, notBetweenFields[0]);
|
|
|
+ Object notStartVal = null;
|
|
|
+ if (notStartMethod != null) {
|
|
|
+ try {
|
|
|
+ notStartVal = notStartMethod.invoke(obj);
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.warn("Failed to invoke method for notStartField: {}",
|
|
|
+ notBetweenFields[0], e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ Method notEndMethod = getMethod(objClass, notBetweenFields[1]);
|
|
|
+ Object notEndVal = null;
|
|
|
+ if (notEndMethod != null) {
|
|
|
+ try {
|
|
|
+ notEndVal = notEndMethod.invoke(obj);
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.warn("Failed to invoke method for notEndField: {}", notBetweenFields[1],
|
|
|
+ e);
|
|
|
}
|
|
|
}
|
|
|
+ if (!ObjectUtils.isEmpty(notStartVal) && !ObjectUtils.isEmpty(notEndVal)) {
|
|
|
+ queryWrapper.notBetween(getSFunction(targetEntityClass, fieldName), notStartVal, notEndVal);
|
|
|
+ }
|
|
|
break;
|
|
|
|
|
|
case EXISTS:
|
|
|
+ // EXISTS 子查询暂不支持,需要手动构建
|
|
|
+ log.debug("EXISTS query keyword is not yet implemented");
|
|
|
break;
|
|
|
case NOT_EXISTS:
|
|
|
+ // NOT EXISTS 子查询暂不支持,需要手动构建
|
|
|
+ log.debug("NOT_EXISTS query keyword is not yet implemented");
|
|
|
break;
|
|
|
case NOT_IN:
|
|
|
// 同IN,取反逻辑
|
|
|
- if (fieldValue != null && fieldValue.toString().contains(",")) {
|
|
|
- List<String> notInList = Arrays.asList(fieldValue.toString().split(","));
|
|
|
- if (!ObjectUtils.isEmpty(notInList)) {
|
|
|
- queryWrapper.notIn(getSFunction(clazz, fieldName), notInList);
|
|
|
+ if (!ObjectUtils.isEmpty(fieldValue)) {
|
|
|
+ if (fieldValue instanceof Collection) {
|
|
|
+ queryWrapper.notIn(getSFunction(targetEntityClass, fieldName),
|
|
|
+ (Collection<?>) fieldValue);
|
|
|
+ } else if (fieldValue.toString().contains(",")) {
|
|
|
+ List<String> notInList = Arrays.asList(fieldValue.toString().split(","));
|
|
|
+ queryWrapper.notIn(getSFunction(targetEntityClass, fieldName), notInList);
|
|
|
+ } else {
|
|
|
+ queryWrapper.notIn(getSFunction(targetEntityClass, fieldName), fieldValue);
|
|
|
}
|
|
|
}
|
|
|
break;
|
|
|
@@ -292,49 +373,64 @@ public class QueryLambdaUtil {
|
|
|
if (StringUtils.isBlank(orderField))
|
|
|
continue;
|
|
|
String direction = parts.length > 1 ? parts[1].trim().toUpperCase() : "ASC";
|
|
|
- String dbOrderField = getDbFieldName(clazz, orderField, tableField);
|
|
|
+ String dbOrderField = getDbFieldName(objClass, orderField, tableField);
|
|
|
if ("DESC".equals(direction)) {
|
|
|
- queryWrapper.orderByDesc(getSFunction(clazz, dbOrderField));
|
|
|
+ queryWrapper.orderByDesc(getSFunction(targetEntityClass, dbOrderField));
|
|
|
} else {
|
|
|
- queryWrapper.orderByAsc(getSFunction(clazz, dbOrderField));
|
|
|
+ queryWrapper.orderByAsc(getSFunction(targetEntityClass, dbOrderField));
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
break;
|
|
|
case ASC:
|
|
|
- queryWrapper.orderByAsc(fieldName);
|
|
|
+ queryWrapper.orderByAsc(getSFunction(targetEntityClass, fieldName));
|
|
|
break;
|
|
|
case RANGE:
|
|
|
// 设置开始的值和结束的值
|
|
|
String[] attribute = queryWapperAnnotation.attribute();
|
|
|
+ if (attribute == null || attribute.length < 2) {
|
|
|
+ log.warn("RANGE query requires 2 attributes, but got: {}",
|
|
|
+ attribute == null ? 0 : attribute.length);
|
|
|
+ break;
|
|
|
+ }
|
|
|
String startRange = attribute[0];
|
|
|
- // 声明属性描述对象
|
|
|
- method = getMethod(clazz, startRange);
|
|
|
- if (method != null) {
|
|
|
- Object val = method.invoke(obj);
|
|
|
- if (!ObjectUtils.isEmpty(val)) {
|
|
|
- queryWrapper.ge(fieldName, val);
|
|
|
+ String endRange = attribute[1];
|
|
|
+
|
|
|
+ // 优先从对象属性获取值
|
|
|
+ Method rangeStartMethod = getMethod(objClass, startRange);
|
|
|
+ Object rangeStartVal = null;
|
|
|
+ if (rangeStartMethod != null) {
|
|
|
+ try {
|
|
|
+ rangeStartVal = rangeStartMethod.invoke(obj);
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.warn("Failed to invoke method for startRange: {}", startRange, e);
|
|
|
}
|
|
|
}
|
|
|
- String endRange = attribute[1];
|
|
|
- method = getMethod(clazz, endRange);
|
|
|
- if (method != null) {
|
|
|
- Object val = method.invoke(obj);
|
|
|
- if (!ObjectUtils.isEmpty(val)) {
|
|
|
- queryWrapper.le(fieldName, val);
|
|
|
+
|
|
|
+ Method rangeEndMethod = getMethod(objClass, endRange);
|
|
|
+ Object rangeEndVal = null;
|
|
|
+ if (rangeEndMethod != null) {
|
|
|
+ try {
|
|
|
+ rangeEndVal = rangeEndMethod.invoke(obj);
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.warn("Failed to invoke method for endRange: {}", endRange, e);
|
|
|
}
|
|
|
}
|
|
|
- // ---属性值查询结束的值----
|
|
|
- // 通过传入的参数查询值
|
|
|
- // 然后通过参数查询
|
|
|
- Object val = param.get(attribute[0]);
|
|
|
- if (!ObjectUtils.isEmpty(val)) {
|
|
|
- queryWrapper.ge(fieldName, val);
|
|
|
+
|
|
|
+ // 如果对象属性没有值,则从 QueryMap 中获取
|
|
|
+ if (ObjectUtils.isEmpty(rangeStartVal)) {
|
|
|
+ rangeStartVal = param.get(startRange);
|
|
|
}
|
|
|
- // 然后通过参数查询
|
|
|
- val = param.get(attribute[1]);
|
|
|
- if (!ObjectUtils.isEmpty(val)) {
|
|
|
- queryWrapper.le(fieldName, val);
|
|
|
+ if (ObjectUtils.isEmpty(rangeEndVal)) {
|
|
|
+ rangeEndVal = param.get(endRange);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 添加范围查询条件
|
|
|
+ if (!ObjectUtils.isEmpty(rangeStartVal)) {
|
|
|
+ queryWrapper.ge(getSFunction(targetEntityClass, fieldName), rangeStartVal);
|
|
|
+ }
|
|
|
+ if (!ObjectUtils.isEmpty(rangeEndVal)) {
|
|
|
+ queryWrapper.le(getSFunction(targetEntityClass, fieldName), rangeEndVal);
|
|
|
}
|
|
|
break;
|
|
|
default:
|
|
|
@@ -344,7 +440,7 @@ public class QueryLambdaUtil {
|
|
|
}
|
|
|
}
|
|
|
} catch (Exception e) {
|
|
|
- e.printStackTrace();
|
|
|
+ log.error("Failed to process query conditions for class: {}", objClass.getName(), e);
|
|
|
}
|
|
|
|
|
|
}
|
|
|
@@ -353,6 +449,34 @@ public class QueryLambdaUtil {
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
+ * 从 MPJLambdaWrapper 中获取目标实体类 T
|
|
|
+ *
|
|
|
+ * @param queryWrapper 查询包装器
|
|
|
+ * @return 目标实体类,如果获取失败则返回 null
|
|
|
+ */
|
|
|
+ @SuppressWarnings("unchecked")
|
|
|
+ private static <T> Class<T> getTargetEntityClass(MPJLambdaWrapper<T> queryWrapper) {
|
|
|
+ try {
|
|
|
+ // 通过反射获取 queryWrapper 的 entityClass 字段
|
|
|
+ Field entityClassField = queryWrapper.getClass().getSuperclass().getDeclaredField("entityClass");
|
|
|
+ entityClassField.setAccessible(true);
|
|
|
+ return (Class<T>) entityClassField.get(queryWrapper);
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.debug("Failed to get entityClass from queryWrapper via reflection, trying alternative method", e);
|
|
|
+ try {
|
|
|
+ // 尝试从父类获取
|
|
|
+ Field entityClassField = queryWrapper.getClass().getSuperclass().getSuperclass()
|
|
|
+ .getDeclaredField("entityClass");
|
|
|
+ entityClassField.setAccessible(true);
|
|
|
+ return (Class<T>) entityClassField.get(queryWrapper);
|
|
|
+ } catch (Exception e2) {
|
|
|
+ log.warn("Cannot get target entity class from queryWrapper", e2);
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
* 获取数据库字段名(处理TableField注解)
|
|
|
*/
|
|
|
private static <T> String getDbFieldName(Class<T> clazz, String fieldName, TableField tableField) {
|
|
|
@@ -363,14 +487,20 @@ public class QueryLambdaUtil {
|
|
|
return StringUtils.camelToUnderline(fieldName);
|
|
|
}
|
|
|
|
|
|
- // 获取get方法
|
|
|
- private static Method getMethod(Class<?> clazz, String filedName) throws Exception {
|
|
|
-// String alpha = filedName.substring(0, 1).toUpperCase();
|
|
|
-// String methodName = "get" + alpha + filedName.substring(1);
|
|
|
-// PropertyDescriptor p = new PropertyDescriptor(filedName, beanClass);
|
|
|
-// Method readMethod = p.getReadMethod();
|
|
|
-
|
|
|
- return OgnlRuntime.getReadMethod(clazz, filedName);
|
|
|
+ /**
|
|
|
+ * 获取字段的 getter 方法
|
|
|
+ *
|
|
|
+ * @param clazz 类对象
|
|
|
+ * @param fieldName 字段名
|
|
|
+ * @return getter 方法,如果不存在则返回 null
|
|
|
+ */
|
|
|
+ private static Method getMethod(Class<?> clazz, String fieldName) {
|
|
|
+ try {
|
|
|
+ return OgnlRuntime.getReadMethod(clazz, fieldName);
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.debug("Failed to get read method for field: {} in class: {}", fieldName, clazz.getName(), e);
|
|
|
+ return null;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
}
|