PageHelper分页
我们在任何的系统中,分页功能是必不可少的。然而,对于这个功能如果有一种快速开发的实现方式,当然可以节省我们很多的时间了。接下来,我就给大家基于不同的环境来说说如何使用一个分页插件:pagehelper
,它是Mybatis
的一个分页插件。
这里使用一个简单的springboot
的demo项目来实现,前台页面使用的Thymeleaf
模板引擎。
首先加入pageHelper
的依赖。
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.2.5</version>
</dependency>
然后在配置文件中加入pageHelper
的相关配置。
# pageHelper配置
# 指定数据库
pagehelper.helper-dialect=mysql
# 页码<=0 查询第一页,页码>=总页数查询最后一页
pagehelper.reasonable=true
# 支持通过 Mapper 接口参数来传递分页参数
pagehelper.support-methods-arguments=true
pageHelper
就可以使用了。
(基本的springboot
的搭建步骤就不说了,之前已经写过文章)
简单的去数据库查一张表,达到分页效果。
dao
层
@Select(value = "select * from address")
List<Map> pageListss();
service
层和serviceImpl
层
List<Map> pageListss( Integer pn);
@Override
public List<Map> pageListss(Integer pn) {
//判断的目的是前台访问的路径没有pn参数,则pn当前页参数默认为1(第一页)
if(pn==null){
pn=1;
}
//参数(当前页,一页展示多少条)
PageHelper.startPage(pn,3);
//只有在startPage下面的第一个select动作会被分页
List<Map> pageList=selectMapper.pageListss();
//把查到的list列表进行pageInfo处理,返回一个分页列表
PageInfo<Map> pageInfo=new PageInfo(pageList);
return pageList;
}
controller
层
@Controller
@RequestMapping(value = "/page")
public class PageController {
@Autowired
SelectService selectService;
@RequestMapping("list")//pn是当前页,页面传给后台
public String list(Integer pn,Model model){
//这时,从service返回来的列表list已经是被分页后的列表了
List<Map> list=selectService.pageListss(pn);
//把分页后的list放到model中,在页面展示信息(thymeleaf模板引擎使用model放置信息)
model.addAttribute("list",list);
return "test";
}
}
test.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>pageHelper练习</title>
</head>
<body>
<table border="1">
<thead>
<tr>
<th>ID</th>
<th>地址</th>
<th>详细地址</th>
<th>电话</th>
<th>账号</th>
</tr>
</thead>
<tbody>
<tr th:each="user : ${list}">
<!-- 将用户的主键 uId 存在在 name 属性中-->
<td th:text="${user.id}"></td>
<td th:text="${user.location}"></td>
<!-- 使用dates对象格式化日期-->
<td th:text="${user.detail}"></td>
<!-- 三运运算判断是否已婚-->
<td th:text="${user.phone}"></td>
<td th:text="${user.account}"></td>
</tr>
</tbody>
</table>
当前第 <span th:text="${list.pageNum}"></span> 页.
总共 <span th:text="${list.pages}"></span> 页.
一共 <span th:text="${list.total}"></span> 条记录
<a th:href="@{/page/list?pn=1}">首页</a>
<a th:href="@{'/page/list?pn='+${list.pageNum-1}}">上一页</a>
<a th:href="@{'/page/list?pn='+${list.pageNum+1}}">下一页</a>
<a th:href="@{'/page/list?pn='+${list.pages}}">尾页</a>
</body>
</html>
访问路径http://localhost:8082/page/list
pn参数会默认会1
结果
说明:上面的${list.pageNum}
,${list.pages}
,${list.total}
等这些属性都是属于list
的,此时这个list
是被分页后的列表,是从service
层传回来的pageInfo
分页列表。
而这个被pageHelper
插件处理后的pageInfo
列表具有诸多属性。
pageInfo
类说明(源码分析)
public class PageInfo<T> implements Serializable {
private static final long serialVersionUID = 1L;
//当前页
private int pageNum;
//每页的数量
private int pageSize;
//当前页的数量
private int size;
//由于startRow和endRow不常用,这里说个具体的用法
//可以在页面中"显示startRow到endRow 共size条数据"
//当前页面第一个元素在数据库中的行号
private int startRow;
//当前页面最后一个元素在数据库中的行号
private int endRow;
//总记录数
private long total;
//总页数
private int pages;
//结果集
private List<T> list;
//前一页
private int prePage;
//下一页
private int nextPage;
//是否为第一页
private boolean isFirstPage = false;
//是否为最后一页
private boolean isLastPage = false;
//是否有前一页
private boolean hasPreviousPage = false;
//是否有下一页
private boolean hasNextPage = false;
//导航页码数
private int navigatePages;
//所有导航页号
private int[] navigatepageNums;
//导航条上的第一页
private int navigateFirstPage;
//导航条上的最后一页
private int navigateLastPage;
public PageInfo() {
}
/**
* 包装Page对象
*
* @param list
*/
public PageInfo(List<T> list) {
this(list, 8);
}
/**
* 包装Page对象
*
* @param list page结果
* @param navigatePages 页码数量
*/
public PageInfo(List<T> list, int navigatePages) {
if (list instanceof Page) {
Page page = (Page) list;
this.pageNum = page.getPageNum();
this.pageSize = page.getPageSize();
this.pages = page.getPages();
this.list = page;
this.size = page.size();
this.total = page.getTotal();
//由于结果是>startRow的,所以实际的需要+1
if (this.size == 0) {
this.startRow = 0;
this.endRow = 0;
} else {
this.startRow = page.getStartRow() + 1;
//计算实际的endRow(最后一页的时候特殊)
this.endRow = this.startRow - 1 + this.size;
}
} else if (list instanceof Collection) {
this.pageNum = 1;
this.pageSize = list.size();
this.pages = this.pageSize > 0 ? 1 : 0;
this.list = list;
this.size = list.size();
this.total = list.size();
this.startRow = 0;
this.endRow = list.size() > 0 ? list.size() - 1 : 0;
}
if (list instanceof Collection) {
this.navigatePages = navigatePages;
//计算导航页
calcNavigatepageNums();
//计算前后页,第一页,最后一页
calcPage();
//判断页面边界
judgePageBoudary();
}
}
.......
}
这里只列出所有属性和构造方法,那么可以清晰的看到一些属性的含义,一些属性是如何初始化,并且初始化值是怎样的,更多详细情况可以自己去查看源码。
以上的分页需求,可以非常方便的使用。
项目经理再也不用担心我的分页了!
-------------------------------------------
个性签名:独学而无友,则孤陋而寡闻。做一个灵魂有趣的人!
如果觉得这篇文章对你有小小的帮助的话,记得在右下角点个“推荐”哦,博主在此感谢!
万水千山总是情,打赏一分行不行,所以如果你心情还比较高兴,也是可以扫码打赏博主,哈哈哈(っ•̀ω•́)っ✎⁾⁾!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· .NET10 - 预览版1新功能体验(一)