前言
我们在做页面查询的时候由于页面无法一次性展示所有的数据,所以采用一种分段式的展示策略—分页查询,实现分页查询的方式有很多种方式,比如sql中的limit,mybatisplus带的分页插件等等,这里我们介绍一下如何在SpringBoot中使用PageHelper插件实现分页查询。
正文PageHelper
PageHelper是针对MyBatis最方便的分页插件PageHelper支持任何复杂的单表,多表查询。 它有以下特点:
PageHelper不支持嵌套结果映射.
PageHelper本质上是两次查询,第一次是对记录总数量的查询,第二次是对记录的查询。
对记录的查询是利用了mybatis提供的拦截器,取得ThreadLocal的pageSize和pageNo,重新拼装分页sql,完成分页。实际上是在sql后面拼接limit来实现的。
limit分页查询的弊端:
当limit offset rows中的offset很大时,会出现效率问题,所以数据规模大是不推荐使用PageHelper来实现分页。
实际的开发过程中我们采用自己手写两次查询,在第二次对记录的查询是采用子查询的方式来对性能进行优化。select * from test where val=4 limit 300000,5
优化成:select * from test a inner join (select id from test where val=4 limit 300000,5) b on a.id=b.id
所以,如果在数据量不大的情况下可以使用PageHelper,否则就不推荐使用PageHelper了。SpringBoot使用PageHelper实现数据分页
Maven依赖
com.github.pagehelper
pagehelper-spring-boot-starter
1.2.5
application.properties:配置类#Paging assistant configuration#配置数据库pagehelper.helper-dialect=mysql#页参数合理化pagehelper.reasonable=true#启用了分页,并且先执行了count后面的查询也拼接了limitpagehelper.support-methods-arguments=true#如果POJO或者Map中发现了countSql属性,就会作为count参数使用pagehelper.params=count=countSql#mybatis logmybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
PageRequestPam:请求的抽象类/** * 分页模糊查询请求的封装类 */@Setter@Getter@ToStringpublic abstract class PageRequestPam implements Serializable { private static final long serialVersionUID = 1L; private int pageNum; //页面序号 private int pageSize; //页面大小}
UserInfoForSearchRes:请求类/** * 这是用户查询的封装类 */@Setter@Getter@ToString@ApiModel("用户查询请求类")public class UserInfoForSearchRes extends PageRequestPam { private static final long serialVersionUID = -5625703056478578435L; @ApiModelProperty( notes = "用户名", example = "xiyuan666") private String userName; @ApiModelProperty( notes = "查询开始时间") private Date searchStartTime; @ApiModelProperty( notes = "查询结束时间") private Date searchEndTime;}
PageUtils:分页的结果工具类public class PageUtils { /** * 将分页信息封装到统一的接口 * @param pam * @param pageInfo * @return */ public static Page getPageResult(PageRequestPam pam, PageInfo> pageInfo) { Page page = new Page(); page.setPageNo(pageInfo.getPageNum()); page.setPageSize(pageInfo.getPageSize()); page.setTotalSize(pageInfo.getTotal()); page.setTotalPages(pageInfo.getPages()); page.setValue(pageInfo.getList()); return page; }}
Page:分页结果的封装类/** * 分页查询的结果封装类 */@Datapublic class Page implements Serializable { private static final long serialVersionUID = 1L; private int pageNo;//当前页 private int pageSize;//当前页大小 private long totalSize;//记录总数 private int totalPages;//页码总数 private Object value;}验证
分页查询接口@PostMapping("/queryUserListPage")@ApiOperation(value = "用户分页模糊查询")@ControllerMethodLogpublic ResponseResult queryUserListPage(@RequestBody UserInfoForSearchRes userInfoForSearchRes) { long startTime = System.currentTimeMillis(); //获取开始时间 int pageNum = userInfoForSearchRes.getPageNum(); int pageSize = userInfoForSearchRes.getPageSize(); PageHelper.startPage(pageNum, pageSize); List
list = userService.getUserInfoByPage(userInfoForSearchRes); Page page= PageUtils.getPageResult(userInfoForSearchRes, new PageInfo
(list)); long endTime = System.currentTimeMillis(); //获取结束时间 log.info("用户模块分页查询-总条数:" + list.size() + "用时:" + (endTime - startTime) + "ms"); return ResponseResult.success(page, ConstantsUtil.QUERY_SUCCESS);}
通过knife4j访问分页查询接口
控制台打印信息
作者:溪源的奇思妙想
原文链接:https://blog.csdn.net/weixin_40990818/article/details/109478502