新增一个扩展的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