手动实现分页查询
实现分页查询是有必要的,首先我们需要知道分页查询的信息:如下
beginPage:首页页码
prevPage: 上一页
nextPage: 下一页
totalPage: 总页数/末页页码
totalCount: 总条数
currentPage: 当前页
pageSize: 每页显示多少条数据
我们通过一个实体类PageResult,初始化上面的几个变量,并简单计算,此类从前端接收到的参数之一currentPage当前页
、pageSize当前页面显示数据条数
,那么其他数据从哪来?
`totalCount总条数`:来自数据库,通过SQL中的COUNT(*)取得所有的条数;
beginPage首页页码
:直接写死,等于1;
totalPage总页数/末页页码
:计算得出,公式是总条数 ÷ 当前显示条数 得到的余数 如果等于0,说明可以被整除,相除的结果就是页数,而如果余数大于0,此时说明剩余的条数小于于一页显示的条数但是大于0条,此时需要新增一页来存放多出的数据,相除结果+1就是页数
,代码表示为this.totalPage = totalCount % pageSize == 0 ? totalCount / pageSize : totalCount / pageSize + 1;
prevPage上一页
:当前页-1,如果此时已经是在第一页,则不再-1,代码表示为:this.prevPage = currentPage - 1 <= 1 ? 1 : currentPage - 1;
nextPage下一页
:当前页+1,如果此时已经是在最后一页,则不再+1,代码表示为:this.nextPage = currentPage + 1 >= totalPage ? totalPage : currentPage + 1;
汇总到PageResult类中就是:
@Data
public class PageResult<T> {
// 两个用户的输入
private int currentPage; // 当前页码
private int pageSize; // 每页显示的条数
// 两条 SQL 语句执行的结果
private int totalCount; // 总条数
private List<T> data; // 当前页结果集数据
// 三个程序计算的数据
private int prevPage; // 上一页页码
private int nextPage; // 下一页页码
private int totalPage; // 总页数/末页页码
// 分页数据通过下面构造期封装好,但思考一下这个构造器什么调用?
public PageResult(int currentPage, int pageSize, int totalCount, List<T> data) {
this.currentPage = currentPage;
this.pageSize = pageSize;
this.totalCount = totalCount;
this.data = data;
// 计算三个数据
// 总页数/末页页码
this.totalPage = totalCount % pageSize == 0 ? totalCount / pageSize : totalCount / pageSize + 1;
// 上一页页码
this.prevPage = currentPage - 1 <= 1 ? 1 : currentPage - 1;
// 下一页页码
this.nextPage = currentPage + 1 >= totalPage ? totalPage : currentPage + 1;
}
}
随后在Controller层接收到currentPage当前页码
、当前pageSize展示条数
后,将数据传入到service层,在service运算
- 1、在实例化PageResult的时候通过构造函数传参,计算出
prevPage上一页
和nextPage下一页
页码 - 2、从数据库中查询到所有数据的条数,并运算出末页页码
- 3、封装到PageResult这类中
我们知道currentPage当前页
的值是给前端用户看的,我们使用Limit实现分页查询,Limit x,y,即从当前数据库的第x行开始显示y条数据,x是从0开始的,所以第一个x的值为currentPage当前页-1
,当我们翻页后第二个x的值应该是第一个x加上每页显示条数y的和,我们在使用MyBtais的时候x和y的位置上是占位符,我们通过#{}表达式取得值,所以在传入参数的时候我们对currentPage当前页
进行运算:start = (currentPage - 1) * pageSize
,我们直接在向x位置的占位符赋值为start
,y位置的占位符赋值为pageSize
,我们使用一个类来封装这2个参数:
@Data
public class QueryObject {
private int currentPage = 1; // 当前页码,要跳转到哪一页的页码(需要给默认值)
private int pageSize = 3; // 每页显示条数(需要给默认值)
private Book book;
// getXxx()方法的返回值可以通过#{xxx}表达式取得,getXxx()方法名中的Xxx首字母小写为xxx后称为属性,和元素(成员变量)不同,属性可以是一个方法的返回值,无需声明
// 属性和元素都可以被#{xxx}表达式取得
public int getStart() {
return (currentPage - 1) * pageSize;
}
}
传入到SQL语句
SELECT * FROM book LIMIT #{start},#{pageSize}
将此查询结果封装到 PageResult中的data参数中,反馈给前端,前端通过取得的book列表来渲染页面,通过取得的各种页码、条数存入变量,用于下一次查询用。