diff --git a/Query.java b/Query.java new file mode 100644 index 0000000..57947e2 --- /dev/null +++ b/Query.java @@ -0,0 +1,236 @@ +package com.utils; + +import java.util.LinkedHashMap; +import java.util.Map; + +import org.apache.commons.lang3.StringUtils; + +import com.baomidou.mybatisplus.plugins.Page; + +/** + * 查询参数工具类 + * + * 核心职责:解析前端传递的查询参数,构建MyBatis-Plus分页对象 + * + * 功能特性: + * 1. 继承LinkedHashMap,保持参数顺序 + * 2. 支持两种参数来源:JQPageInfo和Map + * 3. 自动分页参数计算和SQL注入防护 + * 4. 排序参数解析和处理 + * + * 技术特点: + * - 基于MyBatis-Plus的Page对象 + * - 集成SQL注入过滤 + * - 支持多种前端分页组件参数格式 + */ +public class Query extends LinkedHashMap { + + // 序列化版本ID + private static final long serialVersionUID = 1L; + + /** + * mybatis-plus分页参数 + */ + private Page page; + + /** + * 当前页码 + */ + private int currPage = 1; + + /** + * 每页条数 + */ + private int limit = 10; + + /** + * 构造函数(JQPageInfo版本) + * 通过JQPageInfo对象构建查询参数 + * + * @param pageInfo 分页信息对象,包含分页和排序参数 + */ + public Query(JQPageInfo pageInfo) { + // 分页参数解析 + if (pageInfo.getPage() != null) { + currPage = pageInfo.getPage(); // 设置当前页码 + } + if (pageInfo.getLimit() != null) { + limit = pageInfo.getLimit(); // 设置每页条数 + } + + // 防止SQL注入(因为sidx、order是通过拼接SQL实现排序的,会有SQL注入风险) + String sidx = SQLFilter.sqlInject(pageInfo.getSidx()); // 排序字段安全过滤 + String order = SQLFilter.sqlInject(pageInfo.getOrder()); // 排序方式安全过滤 + + // mybatis-plus分页对象初始化 + this.page = new Page<>(currPage, limit); + + // 排序参数设置 + if (StringUtils.isNotBlank(sidx) && StringUtils.isNotBlank(order)) { + this.page.setOrderByField(sidx); // 设置排序字段 + this.page.setAsc("ASC".equalsIgnoreCase(order)); // 设置排序方向 + } + } + + /** + * 构造函数(Map参数版本) + * 通过Map参数构建查询参数,支持更灵活的参数传递 + * + * @param params 查询参数Map,包含分页、排序等参数 + */ + public Query(Map params) { + // 将参数添加到当前Map中 + this.putAll(params); + + // 分页参数解析 + if (params.get("page") != null) { + // 解析当前页码 + currPage = Integer.parseInt((String) params.get("page")); + } + if (params.get("limit") != null) { + // 解析每页条数 + limit = Integer.parseInt((String) params.get("limit")); + } + + // 计算偏移量并设置到参数中(用于自定义分页查询) + this.put("offset", (currPage - 1) * limit); + this.put("page", currPage); + this.put("limit", limit); + + // 防止SQL注入(排序字段和排序方向的安全过滤) + String sidx = SQLFilter.sqlInject((String) params.get("sidx")); + String order = SQLFilter.sqlInject((String) params.get("order")); + this.put("sidx", sidx); + this.put("order", order); + + // mybatis-plus分页对象初始化 + this.page = new Page<>(currPage, limit); + + // 排序参数设置 + if (StringUtils.isNotBlank(sidx) && StringUtils.isNotBlank(order)) { + this.page.setOrderByField(sidx); // 设置排序字段 + this.page.setAsc("ASC".equalsIgnoreCase(order)); // 设置排序方向 + } + } + + /** + * 获取MyBatis-Plus分页对象 + * + * @return MyBatis-Plus分页对象 + */ + public Page getPage() { + return page; + } + + /** + * 获取当前页码 + * + * @return 当前页码 + */ + public int getCurrPage() { + return currPage; + } + + /** + * 获取每页条数 + * + * @return 每页条数 + */ + public int getLimit() { + return limit; + } + + // 可以添加的增强方法: + + /** + * 获取排序字段 + * + * @return 排序字段名 + */ + public String getSidx() { + return (String) this.get("sidx"); + } + + /** + * 获取排序方向 + * + * @return 排序方向(ASC/DESC) + */ + public String getOrder() { + return (String) this.get("order"); + } + + /** + * 获取偏移量(用于SQL LIMIT查询) + * + * @return 偏移量 + */ + public int getOffset() { + return (int) this.get("offset"); + } + + /** + * 判断是否有排序参数 + * + * @return 是否设置了排序 + */ + public boolean hasSort() { + return StringUtils.isNotBlank(getSidx()) && StringUtils.isNotBlank(getOrder()); + } + + /** + * 获取排序SQL片段 + * + * @return 排序SQL语句,如:"create_time DESC" + */ + public String getOrderByClause() { + if (hasSort()) { + return getSidx() + " " + getOrder().toUpperCase(); + } + return null; + } + + /** + * 添加查询条件 + * + * @param key 条件键 + * @param value 条件值 + * @return 当前对象(支持链式调用) + */ + public Query addCondition(String key, Object value) { + this.put(key, value); + return this; + } + + /** + * 批量添加查询条件 + * + * @param conditions 条件Map + * @return 当前对象(支持链式调用) + */ + public Query addConditions(Map conditions) { + this.putAll(conditions); + return this; + } + + /** + * 验证分页参数有效性 + * + * @return 参数是否有效 + */ + public boolean isValid() { + return currPage > 0 && limit > 0 && limit <= 1000; // 限制每页最大1000条 + } + + /** + * 创建默认查询(第一页,10条) + * + * @return 默认查询对象 + */ + public static Query defaultQuery() { + Map params = new LinkedHashMap<>(); + params.put("page", "1"); + params.put("limit", "10"); + return new Query<>(params); + } +} \ No newline at end of file