新增一个扩展的mybatis-plus构造器,待验证

This commit is contained in:
weitang 2025-05-22 09:44:04 +08:00
parent 14c739d650
commit f3787af369
2 changed files with 163 additions and 0 deletions

View File

@ -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;
}

View File

@ -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);
}
}