pagehelper原理:拦截后面第一条执行sql查询的语句,添加如mysql的limit分页关键词与分页参数,并顺带生成一个查询总数的sql。本质就是个拦截器。
优点:封装分页sql,使我们不需要每个地方都去写分页的查询语句;同时,使我们select的sql语句向下兼容,换了数据库也不需要更改sql分页代码。
官网:https://pagehelper.github.io/
github springboot:https://github.com/pagehelper/pagehelper-spring-boot
一。pom.xml中添加依赖:
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.4.1</version>
</dependency>
二。application.properties中添加配置:
#标识是哪一种数据库
pagehelper.helperDialect=mysql
#启用合理化,如果pageNum<1会查询第一页,如果pageNum>pages会查询最后一页
pagehelper.reasonable=true
#为了支持startPage(Object params)方法,增加了该参数来配置参数映射,用于从对象中根据属性名取值, 可以配置pageNum,pageSize,count,pageSizeZero,reasonable,不配置映射的用默认值, 默认值为pageNum=pageNum;pageSize=pageSize;count=countSql;reasonable=reasonable;pageSizeZero=pageSizeZero
pagehelper.params=count=countSql
#支持通过 Mapper 接口参数来传递分页参数,默认值false,分页插件会从查询方法的参数值中,自动根据上面 params 配置的字段中取值,查找到合适的值时就会自动分页
pagehelper.supportMethodsArguments=true
#如果 pageSize=0 就会查询出全部的结果(相当于没有执行分页查询)
#pagehelper.pageSizeZero=true
三。代码中使用(伪代码):
3.1 ServiceMock业务逻辑层分页查询:
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
@Service
public class ServiceMock {
public HttpResponse getAll(int pageNum, int pageSize) {
//PageHelper.startPage(1, 10, "create_time desc");//排序
PageHelper.startPage(pageNum, pageSize);
List<User> userList = daoMock.selectAll();
PageInfo<User> userPageInfo = new PageInfo<>(userList);
HttpResponse httpResponse = new HttpResponse(0, "查询成功", new Page<>(userPageInfo));
System.out.println(httpResponse);
return httpResponse;
}
}
其中,User是自定义的实体对象。PageInfo是PageHelper提供的分页对象,属性介绍如下:
//当前页
private int pageNum;
//每页的数量
private int pageSize;
//当前页的数量
private int size;
//当前页面第一个元素在数据库中的行号
private int startRow;
//当前页面最后一个元素在数据库中的行号
private int endRow;
//总记录数
private long total;
//总页数
private int pages;
//结果集
private List<T> list;
//第一页
private int firstPage;
//前一页
private int prePage;
//是否为第一页
private boolean isFirstPage;
//是否为最后一页
private boolean isLastPage;
//是否有前一页
private boolean hasPreviousPage;
//是否有下一页
private boolean hasNextPage;
//导航页码数
private int navigatePages;
//所有导航页号
private int[] navigatepageNums;
Page是自定义的分页对象,属性介绍如下:
package demo.page;
import com.github.pagehelper.PageInfo;
import lombok.Data;
import lombok.ToString;
import java.util.List;
@ToString
@Data
public class Page<T> {
private int pageNum;//当前页数
private int pageSize;//页大小
private int totalSize;//总页数
private List<T> list;
public Page(PageInfo<T> pageInfo) {
this.pageNum = pageInfo.getPageNum();
this.pageSize = pageInfo.getPageSize();
this.totalSize = pageInfo.getPages();
this.list = pageInfo.getList();
}
}
HttpResponse是自定义的http接口响应对象,属性如下:
package demo.page;
import lombok.Data;
import lombok.ToString;
@ToString
@Data
public class HttpResponse<T> {
private int code;
private String message;
private T data;
public HttpResponse(int code, String message, T data) {
this.code = code;
this.message = message;
this.data = data;
}
}
分页对象的转换
一般查询出来都是数据库实体对象,需在服务层转成BO业务对象,或者在web层转为VO视图对象,所以封装一个工具类做分页对象的转换。
import java.util.List;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageInfo;
public class PageUtils {
/**
* 转换PageInfo的泛型 K -> V
*
* @param list 数据data
* @param pageInfo 分页对象
* @param <K> 转换前的泛型声明
* @param <V> 转换后的泛型声明
*
* @return 转换后的PageInfo对象
*/
public static <K, V> PageInfo<V> convertPageInfoGenerics(List<V> list, PageInfo<K> pageInfo) {
Page<V> page = new Page<>(pageInfo.getPageNum(), pageInfo.getPageSize());
page.setTotal(pageInfo.getTotal());
PageInfo<V> result = new PageInfo<>(page);
result.setList(list);
return result;
}
}
加上对象的转换后,代码如下:
public PageInfo<String> selectByExample() {
// 分页
PageHelper.startPage(1, 10);
// 查询
CardExample example = new CardExample();
CardExample.Criteria criteria = example.createCriteria();
criteria.andNameLike("%" + "name1" + "%");
List<Card> cardList = cardMapper.selectByExample(example);
// 分页结果
PageInfo<Card> pageInfo = new PageInfo<>(cardList);
// 数据转换
List<String> nameList = pageInfo.getList().stream().map(Card::getName).collect(Collectors.toList());
// 分页结果转换
PageInfo<String> namePageInfo = PageUtils.convertPageInfoGenerics(nameList, pageInfo);
return namePageInfo;
}