You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

236 lines
6.3 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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