mirror of
https://github.com/continew-org/continew-starter.git
synced 2025-09-08 16:57:09 +08:00
refactor: 优化 QueryType 枚举值命名并修复部分错误
This commit is contained in:
@@ -21,8 +21,9 @@ import java.lang.annotation.*;
|
||||
/**
|
||||
* 查询注解
|
||||
*
|
||||
* @author Zheng Jie(<a href="https://gitee.com/elunez/eladmin">ELADMIN</a>)
|
||||
* @author Charles7c
|
||||
* @author Jasmine
|
||||
* @author Zheng Jie(<a href="https://gitee.com/elunez/eladmin">ELADMIN</a>)
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@Target(ElementType.FIELD)
|
||||
@@ -31,15 +32,17 @@ import java.lang.annotation.*;
|
||||
public @interface Query {
|
||||
|
||||
/**
|
||||
* 属性名数组
|
||||
* columns为空 走实体类的字段,并且根据queryType来查询;
|
||||
* columns不为空且columns长度为1,走columns[0]的字段,并且根据queryType来查询;
|
||||
* columns不为空且columns长度大于1,走columns的所有字段, 并且根据queryType来查询; columns之间的处理是OR操作。
|
||||
* 列名
|
||||
*
|
||||
* <p>
|
||||
* columns 为空时,默认取值字段名(自动转换为下划线命名);<br>
|
||||
* columns 不为空且 columns 长度大于 1,多个列查询条件之间为或关系(OR)。
|
||||
* </p>
|
||||
*/
|
||||
String[] columns() default {};
|
||||
|
||||
/**
|
||||
* 查询类型(等值查询、模糊查询、范围查询等)
|
||||
*/
|
||||
QueryType type() default QueryType.EQUAL;
|
||||
QueryType type() default QueryType.EQ;
|
||||
}
|
||||
|
@@ -16,10 +16,10 @@
|
||||
|
||||
package top.charles7c.continew.starter.data.mybatis.plus.query;
|
||||
|
||||
import cn.hutool.core.util.ArrayUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.ArrayUtils;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@@ -30,13 +30,13 @@ import top.charles7c.continew.starter.core.util.validate.ValidationUtils;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* 查询助手
|
||||
*
|
||||
* @author Zheng Jie(<a href="https://gitee.com/elunez/eladmin">ELADMIN</a>)
|
||||
* @author Charles7c
|
||||
* @author Jasmine
|
||||
* @author Zheng Jie(<a href="https://gitee.com/elunez/eladmin">ELADMIN</a>)
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@Slf4j
|
||||
@@ -44,12 +44,12 @@ import java.util.Objects;
|
||||
public class QueryHelper {
|
||||
|
||||
/**
|
||||
* 根据查询条件构建 MyBatis Plus 查询条件封装对象
|
||||
* 根据查询条件构建查询条件封装对象
|
||||
*
|
||||
* @param query 查询条件
|
||||
* @param <Q> 查询条件数据类型
|
||||
* @param <R> 查询数据类型
|
||||
* @return MyBatis Plus 查询条件封装对象
|
||||
* @return 查询条件封装对象
|
||||
*/
|
||||
public static <Q, R> QueryWrapper<R> build(Q query) {
|
||||
QueryWrapper<R> queryWrapper = new QueryWrapper<>();
|
||||
@@ -57,87 +57,80 @@ public class QueryHelper {
|
||||
if (null == query) {
|
||||
return queryWrapper;
|
||||
}
|
||||
// 获取查询条件中所有的字段
|
||||
// 解析并拼接查询条件
|
||||
List<Field> fieldList = ReflectUtils.getNonStaticFields(query.getClass());
|
||||
fieldList.forEach(field -> buildQuery(query, field, queryWrapper));
|
||||
fieldList.forEach(field -> buildWrapper(query, field, queryWrapper));
|
||||
return queryWrapper;
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建 MyBatis Plus 查询条件封装对象
|
||||
* 构建查询条件封装对象
|
||||
*
|
||||
* @param query 查询条件
|
||||
* @param field 字段
|
||||
* @param queryWrapper MyBatis Plus 查询条件封装对象
|
||||
* @param queryWrapper 查询条件封装对象
|
||||
* @param <Q> 查询条件数据类型
|
||||
* @param <R> 查询数据类型
|
||||
*/
|
||||
public static <Q, R> void buildQuery(Q query, Field field, QueryWrapper<R> queryWrapper) {
|
||||
public static <Q, R> void buildWrapper(Q query, Field field, QueryWrapper<R> queryWrapper) {
|
||||
boolean accessible = field.canAccess(query);
|
||||
try {
|
||||
field.setAccessible(true);
|
||||
|
||||
String fieldName = field.getName();
|
||||
String columnName = StrUtil.toUnderlineCase(fieldName);
|
||||
|
||||
// 如果字段值为空,直接返回
|
||||
Object fieldValue = field.get(query);
|
||||
if (ObjectUtil.isEmpty(fieldValue)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 获取 Query 注解信息
|
||||
// 建议:数据库规范中列建议采用下划线连接法命名,程序规范中变量建议采用驼峰法命名
|
||||
String fieldName = field.getName();
|
||||
String columnName = StrUtil.toUnderlineCase(fieldName);
|
||||
// 没有 @Query 注解,默认等值查询
|
||||
Query queryAnnotation = field.getAnnotation(Query.class);
|
||||
// 没有@Query注解,默认走实体类的字段 EQ精确 查询;
|
||||
if (Objects.isNull(queryAnnotation)) {
|
||||
if (null == queryAnnotation) {
|
||||
queryWrapper.eq(columnName, fieldValue);
|
||||
return;
|
||||
}
|
||||
|
||||
// 解析单列查询
|
||||
String[] columns = queryAnnotation.columns();
|
||||
if (ArrayUtils.isEmpty(columns)) {
|
||||
columnName = StrUtil.toUnderlineCase(columnName);
|
||||
} else if (columns.length == 1) {
|
||||
columnName = StrUtil.toUnderlineCase(columns[0]);
|
||||
} else {
|
||||
QueryType queryType = queryAnnotation.type();
|
||||
queryWrapper.and(wrapper -> {
|
||||
for (String column : columns) {
|
||||
String underline = StrUtil.toUnderlineCase(column);
|
||||
// 解析多属性查询
|
||||
switch (queryType) {
|
||||
case EQUAL -> queryWrapper.or().eq(underline, fieldValue);
|
||||
case NOT_EQUAL -> queryWrapper.or().ne(underline, fieldValue);
|
||||
case GREATER_THAN -> queryWrapper.or().gt(underline, fieldValue);
|
||||
case LESS_THAN -> queryWrapper.or().lt(underline, fieldValue);
|
||||
case GREATER_THAN_OR_EQUAL -> queryWrapper.or().ge(underline, fieldValue);
|
||||
case LESS_THAN_OR_EQUAL -> queryWrapper.or().le(underline, fieldValue);
|
||||
case BETWEEN -> {
|
||||
List<Object> between = new ArrayList<>((List<Object>)fieldValue);
|
||||
ValidationUtils.throwIf(between.size() != 2, "[{}] 必须是一个范围", fieldName);
|
||||
queryWrapper.or().between(underline, between.get(0), between.get(1));
|
||||
}
|
||||
case LEFT_LIKE -> queryWrapper.or().likeLeft(underline, fieldValue);
|
||||
case INNER_LIKE -> queryWrapper.or().like(underline, fieldValue);
|
||||
case RIGHT_LIKE -> queryWrapper.or().likeRight(underline, fieldValue);
|
||||
case IN -> {
|
||||
ValidationUtils.throwIfEmpty(fieldValue, "[{}] 不能为空", fieldName);
|
||||
queryWrapper.or().in(underline, (List<Object>)fieldValue);
|
||||
}
|
||||
case NOT_IN -> {
|
||||
ValidationUtils.throwIfEmpty(fieldValue, "[{}] 不能为空", fieldName);
|
||||
queryWrapper.or().notIn(underline, (List<Object>)fieldValue);
|
||||
}
|
||||
case IS_NULL -> queryWrapper.or().isNull(underline);
|
||||
case IS_NOT_NULL -> queryWrapper.or().isNotNull(underline);
|
||||
default -> throw new IllegalArgumentException(String.format("暂不支持 [%s] 查询类型", queryType));
|
||||
}
|
||||
}
|
||||
});
|
||||
final int columnLength = ArrayUtil.length(columns);
|
||||
if (columnLength == 0 || columnLength == 1) {
|
||||
columnName = columnLength == 1 ? columns[0] : columnName;
|
||||
parse(queryAnnotation.type(), columnName, fieldValue, queryWrapper);
|
||||
return;
|
||||
}
|
||||
// 解析查询条件
|
||||
parse(queryAnnotation.type(), columnName, fieldValue, queryWrapper);
|
||||
// 解析多列查询
|
||||
QueryType queryType = queryAnnotation.type();
|
||||
queryWrapper.nested(wrapper -> {
|
||||
for (String column : columns) {
|
||||
switch (queryType) {
|
||||
case EQ -> queryWrapper.or().eq(column, fieldValue);
|
||||
case NE -> queryWrapper.or().ne(column, fieldValue);
|
||||
case GT -> queryWrapper.or().gt(column, fieldValue);
|
||||
case GE -> queryWrapper.or().ge(column, fieldValue);
|
||||
case LT -> queryWrapper.or().lt(column, fieldValue);
|
||||
case LE -> queryWrapper.or().le(column, fieldValue);
|
||||
case BETWEEN -> {
|
||||
List<Object> between = new ArrayList<>((List<Object>)fieldValue);
|
||||
ValidationUtils.throwIf(between.size() != 2, "[{}] 必须是一个范围", fieldName);
|
||||
queryWrapper.or().between(column, between.get(0), between.get(1));
|
||||
}
|
||||
case LIKE -> queryWrapper.or().like(column, fieldValue);
|
||||
case LIKE_LEFT -> queryWrapper.or().likeLeft(column, fieldValue);
|
||||
case LIKE_RIGHT -> queryWrapper.or().likeRight(column, fieldValue);
|
||||
case IN -> {
|
||||
ValidationUtils.throwIfEmpty(fieldValue, "[{}] 不能为空", fieldName);
|
||||
queryWrapper.or().in(column, (List<Object>)fieldValue);
|
||||
}
|
||||
case NOT_IN -> {
|
||||
ValidationUtils.throwIfEmpty(fieldValue, "[{}] 不能为空", fieldName);
|
||||
queryWrapper.or().notIn(column, (List<Object>)fieldValue);
|
||||
}
|
||||
case IS_NULL -> queryWrapper.or().isNull(column);
|
||||
case IS_NOT_NULL -> queryWrapper.or().isNotNull(column);
|
||||
default -> throw new IllegalArgumentException(String.format("暂不支持 [%s] 查询类型", queryType));
|
||||
}
|
||||
}
|
||||
});
|
||||
} catch (BadRequestException e) {
|
||||
log.error("Build query occurred an validation error: {}. Query: {}, Field: {}.", e
|
||||
.getMessage(), query, field, e);
|
||||
@@ -155,30 +148,28 @@ public class QueryHelper {
|
||||
* @param queryType 查询类型
|
||||
* @param columnName 驼峰字段名
|
||||
* @param fieldValue 字段值
|
||||
* @param queryWrapper MyBatis Plus 查询条件封装对象
|
||||
* @param queryWrapper 查询条件封装对象
|
||||
* @param <R> 查询数据类型
|
||||
*/
|
||||
private static <R> void parse(QueryType queryType,
|
||||
String columnName,
|
||||
Object fieldValue,
|
||||
QueryWrapper<R> queryWrapper) {
|
||||
// 解析单个属性查询
|
||||
// 注意:数据库规范中列采用下划线连接法命名,程序规范中变量采用驼峰法命名
|
||||
switch (queryType) {
|
||||
case EQUAL -> queryWrapper.eq(columnName, fieldValue);
|
||||
case NOT_EQUAL -> queryWrapper.ne(columnName, fieldValue);
|
||||
case GREATER_THAN -> queryWrapper.gt(columnName, fieldValue);
|
||||
case LESS_THAN -> queryWrapper.lt(columnName, fieldValue);
|
||||
case GREATER_THAN_OR_EQUAL -> queryWrapper.ge(columnName, fieldValue);
|
||||
case LESS_THAN_OR_EQUAL -> queryWrapper.le(columnName, fieldValue);
|
||||
case EQ -> queryWrapper.eq(columnName, fieldValue);
|
||||
case NE -> queryWrapper.ne(columnName, fieldValue);
|
||||
case GT -> queryWrapper.gt(columnName, fieldValue);
|
||||
case GE -> queryWrapper.ge(columnName, fieldValue);
|
||||
case LT -> queryWrapper.lt(columnName, fieldValue);
|
||||
case LE -> queryWrapper.le(columnName, fieldValue);
|
||||
case BETWEEN -> {
|
||||
List<Object> between = new ArrayList<>((List<Object>)fieldValue);
|
||||
ValidationUtils.throwIf(between.size() != 2, "[{}] 必须是一个范围", columnName);
|
||||
queryWrapper.between(columnName, between.get(0), between.get(1));
|
||||
}
|
||||
case LEFT_LIKE -> queryWrapper.likeLeft(columnName, fieldValue);
|
||||
case INNER_LIKE -> queryWrapper.like(columnName, fieldValue);
|
||||
case RIGHT_LIKE -> queryWrapper.likeRight(columnName, fieldValue);
|
||||
case LIKE -> queryWrapper.like(columnName, fieldValue);
|
||||
case LIKE_LEFT -> queryWrapper.likeLeft(columnName, fieldValue);
|
||||
case LIKE_RIGHT -> queryWrapper.likeRight(columnName, fieldValue);
|
||||
case IN -> {
|
||||
ValidationUtils.throwIfEmpty(fieldValue, "[{}] 不能为空", columnName);
|
||||
queryWrapper.in(columnName, (List<Object>)fieldValue);
|
||||
|
@@ -30,62 +30,72 @@ import lombok.RequiredArgsConstructor;
|
||||
public enum QueryType {
|
||||
|
||||
/**
|
||||
* 等值查询,例如:WHERE `age` = 18
|
||||
* 等于 =,例如:WHERE `age` = 18
|
||||
*/
|
||||
EQUAL(1, "="),
|
||||
EQ,
|
||||
|
||||
/**
|
||||
* 非等值查询,例如:WHERE `age` != 18
|
||||
* 不等于 !=,例如:WHERE `age` != 18
|
||||
*/
|
||||
NOT_EQUAL(2, "!="),
|
||||
NE,
|
||||
|
||||
/**
|
||||
* 大于查询,例如:WHERE `age` > 18
|
||||
* 大于 >,例如:WHERE `age` > 18
|
||||
*/
|
||||
GREATER_THAN(3, ">"),
|
||||
GT,
|
||||
|
||||
/**
|
||||
* 小于查询,例如:WHERE `age` < 18
|
||||
* 大于等于 >= ,例如:WHERE `age` >= 18
|
||||
*/
|
||||
LESS_THAN(4, "<"),
|
||||
GE,
|
||||
|
||||
/**
|
||||
* 大于等于查询,例如:WHERE `age` >= 18
|
||||
* 小于 <,例如:WHERE `age` < 18
|
||||
*/
|
||||
GREATER_THAN_OR_EQUAL(5, ">="),
|
||||
LT,
|
||||
|
||||
/**
|
||||
* 小于等于查询,例如:WHERE `age` <= 18
|
||||
* 小于等于 <=,例如:WHERE `age` <= 18
|
||||
*/
|
||||
LESS_THAN_OR_EQUAL(6, "<="),
|
||||
LE,
|
||||
|
||||
/**
|
||||
* 范围查询,例如:WHERE `age` BETWEEN 10 AND 18
|
||||
*/
|
||||
BETWEEN(7, "BETWEEN"),
|
||||
BETWEEN,
|
||||
|
||||
/**
|
||||
* 左模糊查询,例如:WHERE `nickname` LIKE '%s'
|
||||
* LIKE '%值%',例如:WHERE `nickname` LIKE '%s%'
|
||||
*/
|
||||
LEFT_LIKE(8, "LIKE '%s'"),
|
||||
LIKE,
|
||||
|
||||
/**
|
||||
* 中模糊查询,例如:WHERE `nickname` LIKE '%s%'
|
||||
* LIKE '%值',例如:WHERE `nickname` LIKE '%s'
|
||||
*/
|
||||
INNER_LIKE(9, "LIKE '%s%'"),
|
||||
LIKE_LEFT,
|
||||
|
||||
/**
|
||||
* 右模糊查询,例如:WHERE `nickname` LIKE 's%'
|
||||
* LIKE '值%',例如:WHERE `nickname` LIKE 's%'
|
||||
*/
|
||||
RIGHT_LIKE(10, "LIKE 's%'"),
|
||||
LIKE_RIGHT,
|
||||
|
||||
/**
|
||||
* 包含查询,例如:WHERE `age` IN (10, 20, 30)
|
||||
*/
|
||||
IN(11, "IN"),
|
||||
IN,
|
||||
|
||||
/**
|
||||
* 不包含查询,例如:WHERE `age` NOT IN (20, 30)
|
||||
*/
|
||||
NOT_IN(12, "NOT IN"),
|
||||
NOT_IN,
|
||||
|
||||
/**
|
||||
* 空查询,例如:WHERE `email` IS NULL
|
||||
*/
|
||||
IS_NULL(13, "IS NULL"),
|
||||
IS_NULL,
|
||||
|
||||
/**
|
||||
* 非空查询,例如:WHERE `email` IS NOT NULL
|
||||
*/
|
||||
IS_NOT_NULL(14, "IS NOT NULL"),;
|
||||
|
||||
private final Integer value;
|
||||
private final String description;
|
||||
IS_NOT_NULL,;
|
||||
}
|
||||
|
Reference in New Issue
Block a user