|
|
@@ -1,644 +0,0 @@
|
|
|
-package shop.alien.util.myBaticsPlus;
|
|
|
-
|
|
|
-import com.baomidou.mybatisplus.annotation.TableField;
|
|
|
-import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
|
|
-import com.baomidou.mybatisplus.core.metadata.IPage;
|
|
|
-import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
|
|
-import com.baomidou.mybatisplus.extension.service.IService;
|
|
|
-import lombok.Data;
|
|
|
-import lombok.experimental.Accessors;
|
|
|
-
|
|
|
-import java.lang.reflect.Field;
|
|
|
-import java.lang.reflect.Modifier;
|
|
|
-import java.util.ArrayList;
|
|
|
-import java.util.Collection;
|
|
|
-import java.util.List;
|
|
|
-
|
|
|
-/**
|
|
|
- * 通用查询构建器
|
|
|
- * <p>
|
|
|
- * 功能:根据对象非空字段自动构建查询条件,支持分页、模糊、批量等多种查询方式
|
|
|
- * <p>
|
|
|
- * 使用示例:
|
|
|
- * <pre>{@code
|
|
|
- * // 1. 简单查询
|
|
|
- * QueryBuilder.of(query).build().list(service);
|
|
|
- *
|
|
|
- * // 2. 分页查询
|
|
|
- * QueryBuilder.of(query).page(1, 10).build().page(service);
|
|
|
- *
|
|
|
- * // 3. 批量查询(字段名以_List结尾,如:id_List)
|
|
|
- * QueryBuilder.of(query).build().list(service);
|
|
|
- *
|
|
|
- * // 4. 范围查询(字段名以_Start/_End结尾,如:createdTime_Start, createdTime_End)
|
|
|
- * QueryBuilder.of(query).build().list(service);
|
|
|
- *
|
|
|
- * // 5. 模糊查询(字段名以_Like结尾,如:name_Like)
|
|
|
- * QueryBuilder.of(query).build().list(service);
|
|
|
- * }</pre>
|
|
|
- *
|
|
|
- * @author system
|
|
|
- * @since 2025-01-XX
|
|
|
- */
|
|
|
-public class QueryBuilder<T> {
|
|
|
-
|
|
|
- // ==================== 常量定义 ====================
|
|
|
-
|
|
|
- /** 特殊查询字段后缀(统一使用下划线前缀,避免与普通字段冲突) */
|
|
|
- private static final String SUFFIX_LIST = "_List";
|
|
|
- private static final String SUFFIX_START = "_Start";
|
|
|
- private static final String SUFFIX_END = "_End";
|
|
|
- private static final String SUFFIX_LIKE = "_Like";
|
|
|
-
|
|
|
- /** 模糊查询通配符 */
|
|
|
- private static final String LIKE_WILDCARD = "%";
|
|
|
-
|
|
|
- /** 模糊查询模式枚举 */
|
|
|
- public enum LikeMode {
|
|
|
- /** 前后模糊:%value% */
|
|
|
- BOTH,
|
|
|
- /** 前模糊:%value */
|
|
|
- LEFT,
|
|
|
- /** 后模糊:value% */
|
|
|
- RIGHT
|
|
|
- }
|
|
|
-
|
|
|
- // ==================== 成员变量 ====================
|
|
|
-
|
|
|
- private final T queryEntity;
|
|
|
- private final QueryWrapper<T> wrapper;
|
|
|
- private boolean ignoreEmptyStr = true;
|
|
|
- private boolean stringFieldLike = false; // String类型字段是否默认使用模糊查询
|
|
|
- private final List<String> likeFields = new ArrayList<>(); // 指定哪些字段使用模糊查询
|
|
|
- private LikeMode likeMode = LikeMode.BOTH; // 模糊查询模式(默认前后模糊)
|
|
|
- private Page<T> page;
|
|
|
-
|
|
|
- // ==================== 构造函数 ====================
|
|
|
-
|
|
|
- private QueryBuilder(T queryEntity) {
|
|
|
- this.queryEntity = queryEntity;
|
|
|
- this.wrapper = new QueryWrapper<>();
|
|
|
- }
|
|
|
-
|
|
|
- // ==================== 公开API ====================
|
|
|
-
|
|
|
- /**
|
|
|
- * 创建查询构建器
|
|
|
- */
|
|
|
- public static <T> QueryBuilder<T> of(T queryEntity) {
|
|
|
- return new QueryBuilder<>(queryEntity);
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 设置是否忽略空字符串(默认true)
|
|
|
- */
|
|
|
- public QueryBuilder<T> ignoreEmptyStr(boolean ignore) {
|
|
|
- this.ignoreEmptyStr = ignore;
|
|
|
- return this;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 设置String类型字段是否默认使用模糊查询(默认false,即等值查询)
|
|
|
- */
|
|
|
- public QueryBuilder<T> stringFieldLike(boolean like) {
|
|
|
- this.stringFieldLike = like;
|
|
|
- return this;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 指定哪些字段使用模糊查询(可指定多个字段)
|
|
|
- * 例如:.likeFields("name", "code") 表示 name 和 code 字段使用模糊查询
|
|
|
- */
|
|
|
- public QueryBuilder<T> likeFields(String... fieldNames) {
|
|
|
- if (fieldNames != null) {
|
|
|
- for (String fieldName : fieldNames) {
|
|
|
- if (fieldName != null && !fieldName.trim().isEmpty()) {
|
|
|
- likeFields.add(fieldName.trim());
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- return this;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 设置模糊查询模式(默认前后模糊:%value%)
|
|
|
- *
|
|
|
- * @param mode 模糊查询模式
|
|
|
- * - BOTH: 前后模糊 %value%(默认)
|
|
|
- * - LEFT: 前模糊 %value
|
|
|
- * - RIGHT: 后模糊 value%
|
|
|
- *
|
|
|
- * 使用示例:
|
|
|
- * <pre>{@code
|
|
|
- * QueryBuilder.of(query)
|
|
|
- * .likeFields("name")
|
|
|
- * .likeMode(LikeMode.LEFT) // 前模糊查询
|
|
|
- * .build()
|
|
|
- * }</pre>
|
|
|
- */
|
|
|
- public QueryBuilder<T> likeMode(LikeMode mode) {
|
|
|
- if (mode != null) {
|
|
|
- this.likeMode = mode;
|
|
|
- }
|
|
|
- return this;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 设置分页参数
|
|
|
- */
|
|
|
- public QueryBuilder<T> page(int pageNum, int pageSize) {
|
|
|
- this.page = new Page<>(pageNum, pageSize);
|
|
|
- return this;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 设置分页对象
|
|
|
- */
|
|
|
- public QueryBuilder<T> page(Page<T> page) {
|
|
|
- this.page = page;
|
|
|
- return this;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 构建查询条件
|
|
|
- */
|
|
|
- public QueryResult<T> build() {
|
|
|
- buildBaseQueryConditions();
|
|
|
- processSpecialQueries();
|
|
|
- return new QueryResult<>(this.wrapper, this.page);
|
|
|
- }
|
|
|
-
|
|
|
- // ==================== 核心构建逻辑 ====================
|
|
|
-
|
|
|
- /**
|
|
|
- * 构建基础查询条件(等值查询)
|
|
|
- */
|
|
|
- private void buildBaseQueryConditions() {
|
|
|
- if (queryEntity == null) {
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- List<Field> allFields = getAllFields(queryEntity.getClass());
|
|
|
-
|
|
|
- for (Field field : allFields) {
|
|
|
- if (shouldSkipField(field)) {
|
|
|
- continue;
|
|
|
- }
|
|
|
-
|
|
|
- Object value = getFieldValue(field);
|
|
|
- if (value == null || shouldSkipValue(value)) {
|
|
|
- continue;
|
|
|
- }
|
|
|
-
|
|
|
- String columnName = getColumnName(field);
|
|
|
- if (columnName == null) {
|
|
|
- continue;
|
|
|
- }
|
|
|
-
|
|
|
- Object serializableValue = ensureSerializable(value);
|
|
|
- if (serializableValue != null) {
|
|
|
- String fieldName = field.getName();
|
|
|
-
|
|
|
- // 判断是否使用模糊查询
|
|
|
- boolean shouldUseLike = false;
|
|
|
-
|
|
|
- // 1. 检查是否在指定的模糊查询字段列表中
|
|
|
- if (likeFields.contains(fieldName)) {
|
|
|
- shouldUseLike = true;
|
|
|
- }
|
|
|
- // 2. 检查是否全局启用String字段模糊查询
|
|
|
- else if (stringFieldLike && value instanceof String) {
|
|
|
- shouldUseLike = true;
|
|
|
- }
|
|
|
-
|
|
|
- if (shouldUseLike && value instanceof String) {
|
|
|
- String likeValue = buildLikeValue(serializableValue.toString());
|
|
|
- wrapper.like(columnName, likeValue);
|
|
|
- } else {
|
|
|
- wrapper.eq(columnName, serializableValue);
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 处理特殊查询场景(批量、范围、模糊查询)
|
|
|
- */
|
|
|
- private void processSpecialQueries() {
|
|
|
- if (queryEntity == null) {
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- List<Field> allFields = getAllFields(queryEntity.getClass());
|
|
|
-
|
|
|
- for (Field field : allFields) {
|
|
|
- if (isStaticField(field)) {
|
|
|
- continue;
|
|
|
- }
|
|
|
-
|
|
|
- Object value = getFieldValue(field);
|
|
|
- if (value == null) {
|
|
|
- continue;
|
|
|
- }
|
|
|
-
|
|
|
- String fieldName = field.getName();
|
|
|
-
|
|
|
- // 批量查询:集合类型字段
|
|
|
- if (value instanceof Collection) {
|
|
|
- processBatchQuery(fieldName, (Collection<?>) value);
|
|
|
- continue;
|
|
|
- }
|
|
|
-
|
|
|
- // 范围查询:Start/End 后缀
|
|
|
- if (isRangeQueryField(fieldName)) {
|
|
|
- processRangeQuery(fieldName, value);
|
|
|
- continue;
|
|
|
- }
|
|
|
-
|
|
|
- // 模糊查询:Like 后缀
|
|
|
- if (isLikeQueryField(fieldName)) {
|
|
|
- processLikeQuery(fieldName, value);
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // ==================== 字段过滤判断 ====================
|
|
|
-
|
|
|
- /**
|
|
|
- * 判断是否应该跳过该字段
|
|
|
- */
|
|
|
- private boolean shouldSkipField(Field field) {
|
|
|
- String fieldName = field.getName();
|
|
|
-
|
|
|
- // 跳过特殊查询字段
|
|
|
- if (isSpecialQueryField(fieldName)) {
|
|
|
- return true;
|
|
|
- }
|
|
|
-
|
|
|
- // 跳过 transient 字段
|
|
|
- return Modifier.isTransient(field.getModifiers());
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 判断是否为特殊查询字段(_List/_Start/_End/_Like后缀)
|
|
|
- */
|
|
|
- private boolean isSpecialQueryField(String fieldName) {
|
|
|
- return fieldName.endsWith(SUFFIX_LIST) ||
|
|
|
- fieldName.endsWith(SUFFIX_START) ||
|
|
|
- fieldName.endsWith(SUFFIX_END) ||
|
|
|
- fieldName.endsWith(SUFFIX_LIKE);
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 判断是否为范围查询字段
|
|
|
- */
|
|
|
- private boolean isRangeQueryField(String fieldName) {
|
|
|
- return fieldName.endsWith(SUFFIX_START) || fieldName.endsWith(SUFFIX_END);
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 判断是否为模糊查询字段
|
|
|
- */
|
|
|
- private boolean isLikeQueryField(String fieldName) {
|
|
|
- return fieldName.endsWith(SUFFIX_LIKE);
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 判断是否为静态字段
|
|
|
- */
|
|
|
- private boolean isStaticField(Field field) {
|
|
|
- return Modifier.isStatic(field.getModifiers());
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 判断是否应该跳过该值
|
|
|
- */
|
|
|
- private boolean shouldSkipValue(Object value) {
|
|
|
- // 空字符串
|
|
|
- if (ignoreEmptyStr && value instanceof String && ((String) value).trim().isEmpty()) {
|
|
|
- return true;
|
|
|
- }
|
|
|
-
|
|
|
- // 空集合
|
|
|
- return value instanceof Collection && ((Collection<?>) value).isEmpty();
|
|
|
- }
|
|
|
-
|
|
|
- // ==================== 查询类型处理 ====================
|
|
|
-
|
|
|
- /**
|
|
|
- * 处理批量查询(IN查询)
|
|
|
- */
|
|
|
- private void processBatchQuery(String fieldName, Collection<?> collection) {
|
|
|
- String baseFieldName = removeSuffix(fieldName, SUFFIX_LIST);
|
|
|
- String columnName = getColumnNameByFieldName(baseFieldName, fieldName);
|
|
|
-
|
|
|
- if (columnName != null) {
|
|
|
- List<Object> serializableList = filterSerializableItems(collection);
|
|
|
- if (!serializableList.isEmpty()) {
|
|
|
- wrapper.in(columnName, serializableList);
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 处理范围查询
|
|
|
- */
|
|
|
- private void processRangeQuery(String fieldName, Object value) {
|
|
|
- String baseFieldName = removeSuffix(fieldName, SUFFIX_START, SUFFIX_END);
|
|
|
- String columnName = getColumnNameByFieldName(baseFieldName);
|
|
|
-
|
|
|
- if (columnName != null) {
|
|
|
- Object serializableValue = ensureSerializable(value);
|
|
|
- if (serializableValue != null) {
|
|
|
- if (fieldName.endsWith(SUFFIX_START)) {
|
|
|
- wrapper.ge(columnName, serializableValue);
|
|
|
- } else {
|
|
|
- wrapper.le(columnName, serializableValue);
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 处理模糊查询
|
|
|
- */
|
|
|
- private void processLikeQuery(String fieldName, Object value) {
|
|
|
- String baseFieldName = removeSuffix(fieldName, SUFFIX_LIKE);
|
|
|
- String columnName = getColumnNameByFieldName(baseFieldName);
|
|
|
-
|
|
|
- if (columnName != null && value != null) {
|
|
|
- String likeValue = buildLikeValue(value);
|
|
|
- if (likeValue != null) {
|
|
|
- wrapper.like(columnName, likeValue);
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // ==================== 工具方法 ====================
|
|
|
-
|
|
|
- /**
|
|
|
- * 获取字段值
|
|
|
- */
|
|
|
- private Object getFieldValue(Field field) {
|
|
|
- try {
|
|
|
- field.setAccessible(true);
|
|
|
- return field.get(queryEntity);
|
|
|
- } catch (IllegalAccessException e) {
|
|
|
- return null;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 获取数据库字段名(通过字段对象)
|
|
|
- */
|
|
|
- private String getColumnName(Field field) {
|
|
|
- TableField tableField = field.getAnnotation(TableField.class);
|
|
|
-
|
|
|
- // 检查字段是否标记为不存在
|
|
|
- if (tableField != null && !tableField.exist()) {
|
|
|
- return null;
|
|
|
- }
|
|
|
-
|
|
|
- // 优先使用注解指定的字段名
|
|
|
- if (tableField != null && !tableField.value().isEmpty()) {
|
|
|
- return tableField.value();
|
|
|
- }
|
|
|
-
|
|
|
- // 默认:驼峰转下划线
|
|
|
- return camelToUnderscore(field.getName());
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 获取数据库字段名(通过字段名,支持fallback)
|
|
|
- */
|
|
|
- private String getColumnNameByFieldName(String... fieldNames) {
|
|
|
- for (String fieldName : fieldNames) {
|
|
|
- try {
|
|
|
- Field field = findField(queryEntity.getClass(), fieldName);
|
|
|
- String columnName = getColumnName(field);
|
|
|
- if (columnName != null) {
|
|
|
- return columnName;
|
|
|
- }
|
|
|
- } catch (Exception e) {
|
|
|
- // 继续尝试下一个字段名
|
|
|
- }
|
|
|
- }
|
|
|
- return null;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 移除字段名后缀(精确实现:只移除末尾的后缀)
|
|
|
- *
|
|
|
- * 示例:
|
|
|
- * - removeSuffix("id_List", "_List") → "id"
|
|
|
- * - removeSuffix("createdTime_Start", "_Start") → "createdTime"
|
|
|
- * - removeSuffix("name_Like", "_Like") → "name"
|
|
|
- * - removeSuffix("id_List_List", "_List") → "id_List"(只移除末尾的)
|
|
|
- *
|
|
|
- * @param fieldName 字段名
|
|
|
- * @param suffixes 要移除的后缀(按顺序尝试,找到第一个匹配的就移除)
|
|
|
- * @return 移除后缀后的字段名
|
|
|
- */
|
|
|
- private String removeSuffix(String fieldName, String... suffixes) {
|
|
|
- if (fieldName == null || fieldName.isEmpty()) {
|
|
|
- return fieldName;
|
|
|
- }
|
|
|
-
|
|
|
- // 按顺序尝试每个后缀,找到第一个匹配的就移除
|
|
|
- for (String suffix : suffixes) {
|
|
|
- if (suffix != null && !suffix.isEmpty() && fieldName.endsWith(suffix)) {
|
|
|
- // 只移除末尾的后缀,使用 substring 精确移除
|
|
|
- return fieldName.substring(0, fieldName.length() - suffix.length());
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // 如果没有匹配的后缀,返回原字段名
|
|
|
- return fieldName;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 构建模糊查询值(根据likeMode模式)
|
|
|
- *
|
|
|
- * 模式说明:
|
|
|
- * - BOTH: %value% (前后模糊,默认)
|
|
|
- * - LEFT: %value (前模糊)
|
|
|
- * - RIGHT: value% (后模糊)
|
|
|
- */
|
|
|
- private String buildLikeValue(Object value) {
|
|
|
- if (value == null) {
|
|
|
- return null;
|
|
|
- }
|
|
|
-
|
|
|
- String strValue = value instanceof String ? (String) value : value.toString();
|
|
|
-
|
|
|
- switch (likeMode) {
|
|
|
- case LEFT:
|
|
|
- return LIKE_WILDCARD + strValue; // %value
|
|
|
- case RIGHT:
|
|
|
- return strValue + LIKE_WILDCARD; // value%
|
|
|
- case BOTH:
|
|
|
- default:
|
|
|
- return LIKE_WILDCARD + strValue + LIKE_WILDCARD; // %value%
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 过滤集合中的可序列化元素
|
|
|
- */
|
|
|
- private List<Object> filterSerializableItems(Collection<?> collection) {
|
|
|
- List<Object> result = new ArrayList<>();
|
|
|
- for (Object item : collection) {
|
|
|
- if (item != null && isSerializableType(item)) {
|
|
|
- result.add(item);
|
|
|
- }
|
|
|
- }
|
|
|
- return result;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 确保对象是可序列化的类型
|
|
|
- */
|
|
|
- private Object ensureSerializable(Object value) {
|
|
|
- if (value == null) {
|
|
|
- return null;
|
|
|
- }
|
|
|
-
|
|
|
- if (isSerializableType(value)) {
|
|
|
- return value;
|
|
|
- }
|
|
|
-
|
|
|
- // 尝试转换为字符串
|
|
|
- try {
|
|
|
- return value.toString();
|
|
|
- } catch (Exception e) {
|
|
|
- return null;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 判断对象是否为可序列化的基本类型
|
|
|
- */
|
|
|
- private boolean isSerializableType(Object obj) {
|
|
|
- if (obj == null) {
|
|
|
- return false;
|
|
|
- }
|
|
|
-
|
|
|
- Class<?> clazz = obj.getClass();
|
|
|
-
|
|
|
- return clazz.isPrimitive() ||
|
|
|
- Number.class.isAssignableFrom(clazz) ||
|
|
|
- String.class.equals(clazz) ||
|
|
|
- Boolean.class.equals(clazz) ||
|
|
|
- Character.class.equals(clazz) ||
|
|
|
- java.util.Date.class.isAssignableFrom(clazz) ||
|
|
|
- java.sql.Date.class.isAssignableFrom(clazz) ||
|
|
|
- java.sql.Timestamp.class.isAssignableFrom(clazz) ||
|
|
|
- java.time.LocalDate.class.isAssignableFrom(clazz) ||
|
|
|
- java.time.LocalDateTime.class.isAssignableFrom(clazz);
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 驼峰命名转下划线命名
|
|
|
- */
|
|
|
- private String camelToUnderscore(String camelCase) {
|
|
|
- if (camelCase == null || camelCase.isEmpty()) {
|
|
|
- return camelCase;
|
|
|
- }
|
|
|
-
|
|
|
- StringBuilder result = new StringBuilder();
|
|
|
- for (int i = 0; i < camelCase.length(); i++) {
|
|
|
- char c = camelCase.charAt(i);
|
|
|
- if (Character.isUpperCase(c) && i > 0) {
|
|
|
- result.append('_');
|
|
|
- }
|
|
|
- result.append(Character.toLowerCase(c));
|
|
|
- }
|
|
|
- return result.toString();
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 查找字段(支持父类)
|
|
|
- */
|
|
|
- private Field findField(Class<?> clazz, String fieldName) {
|
|
|
- try {
|
|
|
- return clazz.getDeclaredField(fieldName);
|
|
|
- } catch (NoSuchFieldException e) {
|
|
|
- Class<?> superClass = clazz.getSuperclass();
|
|
|
- if (superClass != null && superClass != Object.class) {
|
|
|
- return findField(superClass, fieldName);
|
|
|
- }
|
|
|
- throw new RuntimeException("字段不存在: " + fieldName + " in " + clazz.getName(), e);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 获取实体类所有字段(包括父类,排除静态字段)
|
|
|
- */
|
|
|
- private List<Field> getAllFields(Class<?> clazz) {
|
|
|
- List<Field> fieldList = new ArrayList<>();
|
|
|
- while (clazz != null && clazz != Object.class) {
|
|
|
- for (Field field : clazz.getDeclaredFields()) {
|
|
|
- if (!isStaticField(field)) {
|
|
|
- fieldList.add(field);
|
|
|
- }
|
|
|
- }
|
|
|
- clazz = clazz.getSuperclass();
|
|
|
- }
|
|
|
- return fieldList;
|
|
|
- }
|
|
|
-
|
|
|
- // ==================== 内部类 ====================
|
|
|
-
|
|
|
- /**
|
|
|
- * 查询结果包装类
|
|
|
- */
|
|
|
- @Data
|
|
|
- @Accessors(chain = true)
|
|
|
- public static class QueryResult<T> {
|
|
|
- private final QueryWrapper<T> wrapper;
|
|
|
- private final Page<T> page;
|
|
|
-
|
|
|
- public QueryResult(QueryWrapper<T> wrapper, Page<T> page) {
|
|
|
- this.wrapper = wrapper;
|
|
|
- this.page = page;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 执行列表查询
|
|
|
- */
|
|
|
- public List<T> list(IService<T> service) {
|
|
|
- return service.list(wrapper);
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 执行分页查询
|
|
|
- */
|
|
|
- public IPage<T> page(IService<T> service) {
|
|
|
- if (page == null) {
|
|
|
- throw new IllegalStateException("未设置分页参数,请先调用page()方法");
|
|
|
- }
|
|
|
- return service.page(page, wrapper);
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 执行单条查询
|
|
|
- */
|
|
|
- public T one(IService<T> service) {
|
|
|
- return service.getOne(wrapper);
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 执行计数查询
|
|
|
- */
|
|
|
- public long count(IService<T> service) {
|
|
|
- return service.count(wrapper);
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 获取查询条件(用于调试)
|
|
|
- */
|
|
|
- public QueryWrapper<T> getWrapper() {
|
|
|
- return wrapper;
|
|
|
- }
|
|
|
- }
|
|
|
-}
|