1 概述
分页查询应该是每个程序员必备的技能,因此我特别花了时间,来整理我使用到的分页组件类
2 Java 2种分页方式
2.1 在代码中实现分页(效率很低)
该方式是从数据库中查询出所有的数据,然后在代码层面进行截取。这种方式不推荐,如果数据量太大,非常耗性能
2.2 数据库中进行分页(推荐)
这种主要通过sql进行分页,就是下面这种方式
select * from student limit 10 offset 1;
3 分页核心组件类
①该组件类主要接收前端数据
/**
* description: 所有有需要的类,继承此类即可
*/
public class ObjectQuery {
/**
* 每页显示记录数,默认为每页10条
*/
private int pageSize = 10;
/**
* 当前页页码,默认当前页为1
*/
private int currentPage = 1;
/**
* 开始时间,时间戳 (这里也可以是Date)
*/
private Long beginTime;
/**
* 结束时间,时间戳 (这里也可以是Date)
*/
private Long endTime;
/**
* 排序字段,通常这里是和前端约定好的 举例:
* 0 入库时间倒序
* 1 入库时间升序
* 2 id升序
* 3 id降序
*
* 这里也可以采用sql拼接的方式,新增两个属性,放弃sort属性
* sortName; 排序字段
* sortOrder; 排序方向
* 然后通过代码,实现sql拼接方式,这种的灵活度最高,但是略微有一点麻烦
*/
private Integer sort;
public int getPageSize() {
return pageSize;
}
public void setPageSize(int pageSize) {
this.pageSize = pageSize;
}
public int getCurrentPage() {
return currentPage;
}
public void setCurrentPage(int currentPage) {
this.currentPage = currentPage;
}
public Long getBeginTime() {
return beginTime;
}
public void setBeginTime(Long beginTime) {
this.beginTime = beginTime;
}
public Long getEndTime() {
return endTime;
}
public void setEndTime(Long endTime) {
this.endTime = endTime;
}
public Integer getSort() {
return sort;
}
public void setSort(Integer sort) {
this.sort = sort;
}
/**
* 这个方法很有用,平常我们拿到currentPage,pageSize一般在Service层手动
* 计算offset,这样代码优雅,并且有点麻烦
* 有了这个方法后,我们可以直接在Mybatis中 使用 #{pageOffset}获取值
* 例如:LIMIT #{pageSize} offset #{pageOffset} 只要传入的对象继承ObjectQuery
* Mybatis会通过反射 调用 getPageSize,getPageOffset方法,即使没有属性也可以
*
* @return offset
*/
public int getPageOffset() {
return (currentPage - 1) * pageSize;
}
}
②该组件类主要返包装数据,返回给前端
/**
* description 返回前端界面的分页包装类
*/
public class PageResult<T> implements Serializable, Cloneable {
/**
* 每页条数
*/
private int pageSize;
/**
* 总记录数
*/
private int totalRecords;
/**
* 当前页
*/
private int currentPage;
/**
* 总页数
*/
private int totalPages;
/**
* 数据集
*/
private List<T> items;
/**
* 构造分页结果
* !!!这是创建分页的唯一入口 这是创建分页的唯一入口 这是创建分页的唯一入口
* !!!没有无参构造器 并且所有方法均为私有,除get方法外
*
* @param pageSize 每页条数
* @param totalRecord 总记录数
* @param currentPage 当前第几页
* @param items 数据集合
*/
public PageResult(int pageSize, int totalRecord, int currentPage, List<T> items) {
setPageSize(pageSize);
// 这一步是从数据库中查询出来的总记录数
this.totalRecords = totalRecord;
// 有了每一页的页数+总记录数,我们可以计算得到总页数
this.totalPages = getTotalPages();
setCurrentPage(currentPage);
this.items = items;
}
private void setPageSize(int pageSize) {
// 默认10条
this.pageSize = pageSize > 0 ? pageSize : 10;
}
private int getTotalPages() {
// 12 % 10 = 2; 9 % 10 = 9 这里主要判断总记录数是不是每页条数的整数倍
int total = this.totalRecords % this.pageSize;
if (total > 0) {
// 12 / 10 = 1; 9 / 10 = 0 利用Java整数除法特性,计算得到正确的总记录数
this.totalPages = this.totalRecords / this.pageSize + 1;
return totalPages;
}
// 总记录数是每页条数的整数倍
this.totalPages = this.totalRecords / this.pageSize;
return totalPages;
}
private void setCurrentPage(int currentPage) {
// 如果当前页不是正整数,则赋值为1 !!这里也可以考虑直接抛出异常或者在构造器最开始的时候,就进行参数校验
if (currentPage == 0 || currentPage < 0) {
this.currentPage = 1;
return;
}
/*
* 如果当前页大于总页数,那么就把当前页设置为总页数
* 不难想到,在这种情况下,是没有任何数据的,及items为空
*
* 举例: pageSize :10
* totalRecords : 13
* totalPages : 2
* currentPage : 3
* 那么查询就是 (currentPage -1) * pageSize 及从第20条开始查询,总共才13条,自然没有数据
* !!但是,一般情况下,currentPage > totalPages是不会发生的,这里有两种方式会导致该情况发生
* ①前端 页面传错参数
* ②有人直接通过API及接口调用,并且传入错误的参数
*
*/
if (currentPage > getTotalPages()) {
this.currentPage = totalPages;
return;
}
this.currentPage = currentPage;
}
/*------------------------所有属性的get方法必须存在,反射会用到-----------------------*/
public List<T> getItems() {
return items;
}
public int getPageSize() {
return this.pageSize > 0 ? this.pageSize : 10;
}
public int getTotalRecords() {
return this.totalRecords;
}
public int getCurrentPage() {
return this.currentPage;
}
}
请尊重作者劳动成果,转载请注明出处。以上内容若有侵权,请联系作者,立即删除