PageHelper 地址:https://pagehelper.github.io/

Maven依赖
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>最新版本</version>
</dependency>
或者直接用 二选一
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>最新版本</version>
</dependency>
PageHelper配置类
import com.github.pagehelper.PageHelper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.Properties;
@Configuration
public class PageHelperConfig {
@Bean
public PageHelper pageHelper() {
PageHelper pageHelper = new PageHelper();
Properties p = new Properties();
p.setProperty("offsetAsPageNum", "true");
p.setProperty("rowBoundsWithCount", "true"); // 将该参数设置为 true 后,offset会当成 pageNum 使用,limit 和 pageSize 含义相同。
p.setProperty("reasonable", "true"); // reasonable 为 true,这时如果 pageNum<=0 会查询第一页,如果 pageNum>总页数 会查询最后一页。
p.setProperty("dialect", "mysql"); // 配置mysql数据库
pageHelper.setProperties(p);
return pageHelper;
}
}
PageHelper 主要用法
在serviceimpl 执行mapper前 加入 PageHelper.startPage(page, pageSize)。
说明:startPage是个静态方法,他的作用白话是:紧跟在这个方法后的第一个MyBatis 查询方法会被进行分页。但是要深入记忆的一点是:startPage()实现与ThreadLocal一样:是执行startPage()时,会记录线程信息,之后的此线程第一次Select会被执行分页。分页后,PageHelper会在其自己finally块执行clearPage()。
PageHelper乱分页问题产生原因
List<User> list;
PageHelper.startPage(1, 10);
if(param1 != null){
list = userMapper.selectIf(param1);
} else {
list = new ArrayList<User>();
}
上文代码看似没啥问题,但是要记住PageHelper.startPage是线程级别的分页,一旦这个线程A出现异常,但是这个PageHelper没有对线程A执行PageHelper.clearPage();就会导致下个接口使用线程A时,出现各种各样的异常。所以最保险的情况就是
PageHelper.startPage(1, 10);
try{
// todo 做业务查询
} finally {
PageHelper.clearPage();
}
最后附上日常开发API
PageHelper.clearPage(); // 清除此线程的下次查询的分页
// PageHelper.startPage(page, pageSize,false); // 通过PageInfo得到的total是-1
// PageHelper.startPage(page, pageSize,true); 等价于 PageHelper.startPage(page, pageSize);
PageHelper.startPage(page, pageSize); //此语句会PageHelper自动执行有count计数 可通过PageInfo.getTotal(),得到查询的结果数。
new PageInfo<>(xxxMapper.selectByAllWithCondition(obj));
或者
PageHelper.startPage(pageNo, pageSize);
// 执行查询
List<YourEntity> list = yourMapper.selectAll();
// 获取分页信息(PageHelper会自动计算total)
PageInfo<YourEntity> pageInfo = new PageInfo<>(list);
附上一个工具类
推荐看完上文,了解基本信息。(可以找Gpt进行优化与拓展)
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import java.util.*;
import java.util.function.Supplier;
/**
* 轻量分页工具:仅负责启动分页并返回 PageInfo。
* 特性:
* 1. 兼容 JDK8(不使用 String.isBlank)。
* 2. 支持可选 orderBy,但做白名单过滤防止 SQL 注入。
* 3. 统一页码/尺寸安全处理并限制最大 pageSize。
*/
public final class SimplePage {
// 展示使用方式
public static void main(String[] args) {
int pageNum = 1;
int pageSize = 10;
// 下面放了2个可使用的案例
// PageInfo<Object> page = SimplePage.page(pageNum, pageSize,
// () -> aMapper.selectList());
//
// PageInfo<Object> page1 = SimplePage.page(pageNum, pageSize, "drop_rate desc",
// () -> aMapper.selectList());
}
// 允许的排序列(根据实际表字段维护)
private static final Set<String> ORDER_BY_WHITELIST =
new HashSet<>(Arrays.asList("id", "create_time", "update_time", "drop_rate"));
private static final int DEFAULT_PAGE_NUM = 1;
private static final int DEFAULT_PAGE_SIZE = 10;
private static final int MAX_PAGE_SIZE = 500;
private SimplePage() {}
public static <T> PageInfo<T> page(int pageNum, int pageSize, Supplier<List<T>> supplier) {
PageHelper.startPage(normalizePageNum(pageNum), normalizePageSize(pageSize));
return buildPageInfo(supplier);
}
public static <T> PageInfo<T> page(int pageNum, int pageSize, String orderBy, Supplier<List<T>> supplier) {
int pn = normalizePageNum(pageNum);
int ps = normalizePageSize(pageSize);
String safeOrderBy = buildSafeOrderBy(orderBy);
if (safeOrderBy != null) {
PageHelper.startPage(pn, ps, safeOrderBy);
} else {
PageHelper.startPage(pn, ps);
}
return buildPageInfo(supplier);
}
private static <T> PageInfo<T> buildPageInfo(Supplier<List<T>> supplier) {
List<T> list = supplier == null ? Collections.emptyList() : supplier.get();
if (list == null) {
list = Collections.emptyList();
}
return new PageInfo<>(list);
}
private static int normalizePageNum(int v) {
return v < 1 ? DEFAULT_PAGE_NUM : v;
}
private static int normalizePageSize(int v) {
if (v < 1) return DEFAULT_PAGE_SIZE;
return Math.min(v, MAX_PAGE_SIZE);
}
private static boolean hasText(String s) {
return s != null && !s.trim().isEmpty();
}
/**
* 解析并校验 orderBy(示例支持: column [asc|desc],多列可按需扩展)
*/
private static String buildSafeOrderBy(String raw) {
if (!hasText(raw)) return null;
String trimmed = raw.trim();
// 拆分(只允许一列,若需多列可 split(",") 再循环校验)
String[] parts = trimmed.split("\\s+");
String col = parts[0].toLowerCase(Locale.ROOT);
if (!ORDER_BY_WHITELIST.contains(col)) {
return null; // 非白名单列,忽略排序
}
String direction = "asc";
if (parts.length > 1) {
String d = parts[1].toLowerCase(Locale.ROOT);
if ("desc".equals(d) || "asc".equals(d)) {
direction = d;
}
}
return col + " " + direction;
}
}
特殊说明:
上述文章均是作者实际操作后产出。烦请各位,请勿直接盗用!转载记得标注原文链接:www.zanglikun.com
第三方平台不会及时更新本文最新内容。如果发现本文资料不全,可访问本人的Java博客搜索:标题关键字。以获取最新全部资料 ❤
免责声明: 本站文章旨在总结学习互联网技术过程中的经验与见解。任何人不得将其用于违法或违规活动!所有违规内容均由个人自行承担,与作者无关。
第三方平台不会及时更新本文最新内容。如果发现本文资料不全,可访问本人的Java博客搜索:标题关键字。以获取最新全部资料 ❤
免责声明: 本站文章旨在总结学习互联网技术过程中的经验与见解。任何人不得将其用于违法或违规活动!所有违规内容均由个人自行承担,与作者无关。

评论(0)