新增一个扩展的mybatis-plus构造器,待验证
This commit is contained in:
parent
14c739d650
commit
f3787af369
@ -0,0 +1,15 @@
|
|||||||
|
package com.yfd.platform.utils.wrapper;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import org.springframework.data.domain.Sort;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class QueryCondition {
|
||||||
|
private Integer page;
|
||||||
|
private Integer size;
|
||||||
|
private Map<String, Object> filters;
|
||||||
|
private Sort sort;
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,148 @@
|
|||||||
|
package com.yfd.platform.utils.wrapper;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
|
import org.springframework.data.domain.Sort;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
public class QueryWrapperBuilder {
|
||||||
|
// 字段缓存:类 -> 字段名集合(包含驼峰和下划线格式)
|
||||||
|
private static final Map<Class<?>, Set<String>> FIELD_CACHE = new ConcurrentHashMap<>();
|
||||||
|
/**
|
||||||
|
* 将 QueryCondition 转换为 MyBatis-Plus 的 QueryWrapper
|
||||||
|
*
|
||||||
|
* @param condition 查询条件
|
||||||
|
* @param entityClass 实体类(用于字段合法性校验)
|
||||||
|
* @return QueryWrapper<T>
|
||||||
|
*/
|
||||||
|
public static <T> QueryWrapper<T> build(QueryCondition condition, Class<T> entityClass) {
|
||||||
|
QueryWrapper<T> wrapper = new QueryWrapper<>();
|
||||||
|
|
||||||
|
|
||||||
|
// 修改 build 方法中的过滤条件处理部分
|
||||||
|
condition.getFilters().forEach((field, value) -> {
|
||||||
|
if (isValidField(field, entityClass)) {
|
||||||
|
String column = camelToUnderline(field);
|
||||||
|
|
||||||
|
// 解析运算符(示例格式:age_gt=30)
|
||||||
|
if (field.contains("__")) { // 使用双下划线分隔符更安全
|
||||||
|
String[] parts = field.split("__");
|
||||||
|
if (parts.length == 2) {
|
||||||
|
String realField = parts[0];
|
||||||
|
String operator = parts[1];
|
||||||
|
column = camelToUnderline(realField);
|
||||||
|
applyOperator(wrapper, column, operator, value);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 默认等值查询
|
||||||
|
wrapper.eq(column, value);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 处理排序
|
||||||
|
if (condition.getSort() != null) {
|
||||||
|
condition.getSort().forEach(order -> {
|
||||||
|
String column = camelToUnderline(order.getProperty());
|
||||||
|
if (order.isAscending()) {
|
||||||
|
wrapper.orderByAsc(column);
|
||||||
|
} else {
|
||||||
|
wrapper.orderByDesc(column);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return wrapper;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 在字段校验时增加格式检查
|
||||||
|
private static boolean isValidField(String field) {
|
||||||
|
// 只允许字母、数字和下划线
|
||||||
|
return field.matches("^[a-zA-Z0-9_]+$");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 运算符处理方法
|
||||||
|
private static <T> void applyOperator(QueryWrapper<T> wrapper, String column, String operator, Object value) {
|
||||||
|
switch (operator.toLowerCase()) {
|
||||||
|
case "eq":
|
||||||
|
wrapper.eq(column, value);
|
||||||
|
break;
|
||||||
|
case "ne":
|
||||||
|
wrapper.ne(column, value);
|
||||||
|
break;
|
||||||
|
case "gt":
|
||||||
|
wrapper.gt(column, value);
|
||||||
|
break;
|
||||||
|
case "ge":
|
||||||
|
wrapper.ge(column, value);
|
||||||
|
break;
|
||||||
|
case "lt":
|
||||||
|
wrapper.lt(column, value);
|
||||||
|
break;
|
||||||
|
case "le":
|
||||||
|
wrapper.le(column, value);
|
||||||
|
break;
|
||||||
|
case "like":
|
||||||
|
wrapper.like(column, value);
|
||||||
|
break;
|
||||||
|
case "notlike":
|
||||||
|
wrapper.notLike(column, value);
|
||||||
|
break;
|
||||||
|
case "in":
|
||||||
|
if (value instanceof Collection) {
|
||||||
|
wrapper.in(column, (Collection<?>) value);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new IllegalArgumentException("不支持的运算符: " + operator);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 驼峰转下划线(工具方法)
|
||||||
|
private static String camelToUnderline(String str) {
|
||||||
|
return str.replaceAll("([a-z0-9])([A-Z])", "$1_$2").toLowerCase();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 下划线转驼峰(支持反向校验)
|
||||||
|
private static String underlineToCamel(String str) {
|
||||||
|
if (!str.contains("_")) {
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
String[] parts = str.split("_");
|
||||||
|
sb.append(parts[0]);
|
||||||
|
for (int i = 1; i < parts.length; i++) {
|
||||||
|
if (!parts[i].isEmpty()) {
|
||||||
|
sb.append(Character.toUpperCase(parts[i].charAt(0)));
|
||||||
|
sb.append(parts[i].substring(1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 字段合法性校验(扩展点)
|
||||||
|
private static <T> boolean isValidField(String field, Class<T> entityClass) {
|
||||||
|
// 双重校验:1.原始字段 2.驼峰转下划线反向校验
|
||||||
|
return containsField(entityClass, field) ||
|
||||||
|
containsField(entityClass, underlineToCamel(field));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static <T> boolean containsField(Class<T> entityClass, String fieldName) {
|
||||||
|
// 获取或缓存字段集合
|
||||||
|
Set<String> fields = FIELD_CACHE.computeIfAbsent(entityClass, clazz ->
|
||||||
|
Arrays.stream(clazz.getDeclaredFields())
|
||||||
|
.map(Field::getName)
|
||||||
|
.collect(Collectors.toSet())
|
||||||
|
);
|
||||||
|
|
||||||
|
return fields.contains(fieldName);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user