|
|
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<T> extends LinkedHashMap<String, Object> {
|
|
|
|
|
|
// 序列化版本ID
|
|
|
private static final long serialVersionUID = 1L;
|
|
|
|
|
|
/**
|
|
|
* mybatis-plus分页参数
|
|
|
*/
|
|
|
private Page<T> 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<String, Object> 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<T> 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<T> addCondition(String key, Object value) {
|
|
|
this.put(key, value);
|
|
|
return this;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 批量添加查询条件
|
|
|
*
|
|
|
* @param conditions 条件Map
|
|
|
* @return 当前对象(支持链式调用)
|
|
|
*/
|
|
|
public Query<T> addConditions(Map<String, Object> conditions) {
|
|
|
this.putAll(conditions);
|
|
|
return this;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 验证分页参数有效性
|
|
|
*
|
|
|
* @return 参数是否有效
|
|
|
*/
|
|
|
public boolean isValid() {
|
|
|
return currPage > 0 && limit > 0 && limit <= 1000; // 限制每页最大1000条
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 创建默认查询(第一页,10条)
|
|
|
*
|
|
|
* @return 默认查询对象
|
|
|
*/
|
|
|
public static <T> Query<T> defaultQuery() {
|
|
|
Map<String, Object> params = new LinkedHashMap<>();
|
|
|
params.put("page", "1");
|
|
|
params.put("limit", "10");
|
|
|
return new Query<>(params);
|
|
|
}
|
|
|
} |