分页查询
分页查询的优点
所谓分页,就是查询结果数据较多时,采用按页显示的方法,而不是一次性全部显示
分页的优点:
服务器:一次性查询所有信息,服务器压力大,分页查询服务器压力小
客户端:一次性显示所有信息,需要更多流量,加载时间也会更长,分页显示没有这个问题
用户体验上:一般最有价值的信息都会在前几页显示,也方便用户记忆,多查询出来的数据使用几率很低
实现分页查询需要我们开发过程中多几个步骤
PageHelper实现分页查询原理
我们可以使用sql语句中添加limit关键字的方法实现分页查询
但是查询分页内容时,我们要自己计算相关的分页信息和参数
limit 0,10 limit 10,10
分页逻辑无论什么业务都是类似的,所以有框架帮助我们高效实现分页功能
PageHelper框架可以实现我们提供页码和每页条数,自动实现分页效果,收集分页信息
PageHelper的分页原理就是在程序运行时,在sql语句尾部添加limit关键字,并按照分页信息向limit后追加分页数据
要想使用,首先还是添加依赖
我们在之前搭建的微服务项目中先编写学习,建议使用csmall-order模块
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
</dependency>
在添加seata支持时已经添加了pagehepler依赖
PageHelper的基本使用
编写持久层
我们使用csmall-order-webapi模块来完成分页的测试
首先编写分页的持久层mapper,持久层功能是全查所有订单信息
OrderMapper添加方法
// 分页显示所有订单的方法
// PageHelper框架完成分页的原理是在运行的sql语句后自动添加limit关键字
// 所以我们在编写查询方法之前,无需关注分页操作,持久层编写分页查询和普通查询没有区别
// 无论注解还是xml文件都没有区别
@Select("select id,user_id,commodity_code,count,money from order_tbl")
List<Order> findAllOrders();
注意这个方法并不需要任何分页的参数或返回值,sql也不需要编写limit
都是在业务逻辑层中由PageHelper框架处理的
编写业务逻辑层
下面就转到业务逻辑层实现类,先编写一个方法使用PageHelper的功能
先不用写接口,直接在业务逻辑层实现类中写方法
OrderServiceImpl添加方法
// 分页查询所有订单的业务逻辑层方法
// page是页码,pageSize是每页条数
public PageInfo<Order> getAllOrderByPage(Integer page,Integer pageSize){
// PageHelper框架实现分页的核心操作:
// 在要执行分页的查询运行之前,设置分页的条件
// 设置的方式如下(固定的格式,PageHelper框架设计的)
// PageHelper设置page为1就是查询第一页
PageHelper.startPage(page,pageSize);
// 下面开始持久层方法的调用
// 此方法运行时因为上面设置了分页条件,sql语句中会自动出现limit关键字
List<Order> list = orderMapper.findAllOrders();
// 查询结果list中包含的就是分页查询范围的数据了
// 但是这个数据不包含分页信息(总页数,总条数,是否是首页,是否是末页等)
// 我们要利用PageHelper框架提供的PageInfo类型,来进行返回
// PageInfo对象可以既包含分页数据,又包含分页信息
// 这些信息会在PageInfo对象实例化时自动计算,并赋值到PageInfo对象中
return new PageInfo<>(list);
}
编写控制层
打开OrderController新建方法
@Autowired
// ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
private OrderServiceImpl orderService;
//...
@GetMapping("/page")
@ApiOperation("分页查询所有订单")
@ApiImplicitParams({
@ApiImplicitParam(value = "页码",name="page",example ="1" ),
@ApiImplicitParam(value = "每页条数",name="pageSize",example ="10" )
})
public JsonResult<PageInfo<Order>> pageOrder(Integer page,Integer pageSize){
PageInfo<Order> pageInfo=
orderService.getAllOrdersByPage(page,pageSize);
return JsonResult.ok("查询完成",pageInfo);
}
启动Nacos\Seata
启动order
进行knife4j测试http://localhost:20002/doc.html#/home
可以观察控制台输出的运行的sql语句(会自动添加limit关键字)
PageInfo对象既包含查询数据结果,又包含分页信息
数据结构如下图

附:PageInfo全部分页信息属性
//当前页
private int pageNum;
//每页的数量
private int pageSize;
//当前页的行数量
private int size;
//当前页面第一个元素在数据库中的行号
private int startRow;
//当前页面最后一个元素在数据库中的行号
private int endRow;
//总页数
private int pages;
//前一页页号
private int prePage;
//下一页页号
private int nextPage;
//是否为第一页
private boolean isFirstPage;
//是否为最后一页
private boolean isLastPage;
//是否有前一页
private boolean hasPreviousPage;
//是否有下一页
private boolean hasNextPage;
//导航条中页码个数
private int navigatePages;
//所有导航条中显示的页号
private int[] navigatepageNums;
//导航条上的第一页页号
private int navigateFirstPage;
//导航条上的最后一页号
private int navigateLastPage;