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