分页查询的理解和实现步骤
所谓分页,就是查询结果数据较多时,采用按页显示的方法,而不是一次性全部显示1. 对于服务器:一次性查询所有信息,服务器压力大,分页查询服务器压力小2. 对于客户端:一次性显示所有信息,需要更多流量,加载时间也会更长,分页显示没有这个问题3. 在用户体验上:一般最有价值的信息都会在前几页显示,也方便用户记忆,多查询出来的数据使用几率很低...
分页查询的优点:
所谓分页,就是查询结果数据较多时,采用按页显示的方法,而不是一次性全部显示
1. 对于服务器:
一次性查询所有信息,服务器压力大,分页查询服务器压力小
2. 对于客户端:
一次性显示所有信息,需要更多流量,加载时间也会更长,分页显示没有这个问题
3. 在用户体验上:
一般最有价值的信息都会在前几页显示,也方便用户记忆,多查询出来的数据使用几率很低
实现分页查询
我们可以使用sql语句中添加limit关键字的方法实现分页查询
但是查询分页内容时,我们要自己计算相关的分页信息和参数
limit 0,10 limit 10,10
分页逻辑无论什么业务都是类似的,所以有框架帮助我们高效实现分页功能
PageHelper框架可以实现我们提供页码和每页条数,自动实现分页效果,收集分页信息
PageHepler框架实现分页最核心的代码就是在运行要分页的查询语句之前
PageHelper的分页原理就是在程序运行时,在sql语句尾部添加limit关键字,并按照分页信息向limit后追加分页数据。
要想使用,首先还是添加依赖。
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
</dependency>
但是,当前我们分页查询返回的类型是PageInfo
如果用这个类型来做业务逻辑层的返回值,当当前方法作为dubbo生产者对外提供服务时
消费者调用该服务需要使用PageInfo类型对象来接收,这样要求消费者也添加PageHepler依赖,这是不合理的
所以我们设计在通用的commons模块中,添加一个专门用于返回分页结果的类JsonPage,代替PageInfo
这样当前微服务项目中,所有分页或类似的操作,就都可以使用这个类了
例如SpringDataElasticsearch框架也支持分页,返回类型为Page,它也可以替换为JsonPage
因为需要在commons模块中使用PageInfo类型,所以commons模块要添加pageHelper的依赖。
<!-- 为了将PageHelper框架中分页查询返回值PageInfo转换为JsonPage,添加的依赖 -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.2.0</version>
</dependency>
需要新建一个JsonPage类, 通用的返回各种类型分页结果的信息类
根据实际需求,定义需要的分页信息,实际开发中可能较多,我们这里就声明4个基本的
编写一个将PageInfo类型转换为JsonPage类型的方法
如果需要将其它框架的分页对象转换,例如SpringData的Page类,那么就再编写新的方法即可
进行转换:基本思路是将pageInfo对象中的数据赋值给JsonPage对象
赋值分页信息
赋值分页数据
return返回
package cn.tedu.mall.common.restful;
import com.github.pagehelper.PageInfo;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
/**
* <p>数据分页类</p>
*
* @param <T> 列表数据
*/
@Data
public class JsonPage<T> implements Serializable {
@ApiModelProperty(value = "当前页码", name = "page")
private Integer page;
@ApiModelProperty(value = "分页条数", name = "pageSize")
private Integer pageSize;
@ApiModelProperty(value = "总页数", name = "totalPage")
private Integer totalPage;
@ApiModelProperty(value = "总记录数", name = "total")
private Long total;
@ApiModelProperty(value = "分页数据", name = "list")
private List<T> list;
/**
* 将PageHelper分页后的list转为分页信息
*/
public static <T> JsonPage<T> restPage(PageInfo<T> pageInfo) {
JsonPage<T> result = new JsonPage<T>();
result.setTotalPage(pageInfo.getPages());
result.setPage(pageInfo.getPageNum());
result.setPageSize(pageInfo.getPageSize());
result.setTotal(pageInfo.getTotal());
result.setList(pageInfo.getList());
return result;
}
}
编写持久层
我们使用csmall-order-webapi模块来完成分页的测试
首先编写分页的持久层mapper,持久层功能是全查所有订单信息
OrderMapper添加方法--分页查询全部订单
@Select("select id,user_id,commodity_code,count,money from order_tbl")
List<Order> findAllOrders();
编写业务层
OrderService业务逻辑层接口项目添加方法
返回JsonPage类型的分页查询全部订单方法
page 是页码
pageSize 是每页条数
JsonPage<Order> getAllOrdersByPage(Integer page,Integer pageSize);
在OrderServiceImpl实现类中写业务实现逻辑
重写方法getAllOrdersByPage(Integer page, Integer pageSize)
PageHepler框架实现分页最核心的代码就是在运行要分页的查询语句之前
通过框架给定的方法设置要分页查询的要求(第几页,每页多少条)
参数page和SpringData框架的设计不同,page为1就是第一页,page为2就是第二页
当设置完分页要求后,下面紧随的下一次查询, 就会自动在sql语句末尾添加limit关键字,limit后面的值就是按page,pageSize得出的
list并不是全部的订单的集合,而是按上面分页条件查询出的分页数据,在返回时不直接返回list对象,而是返回PageHelper框架提供的PageInfo类型对象 ,这个对象PageInfo既包含查询数据结果,又包含分页信息,可以保存list集合的同时,还能自动计算分页信息
最后将得到的PageInto对象用JsonPage的restPage替换,返回数据
// 分页查询所有订单的方法
public JsonPage<Order> getAllOrdersByPage(Integer page, Integer pageSize){
PageHelper.startPage(page,pageSize);
List<Order> list= orderMapper.findAllOrders();
return JsonPage.restPage(new PageInfo<>(list));
}
编写控制层
在OrderController类中添加调用分页方法
@GetMapping("/page")
@ApiOperation("分页查询所有订单")
@ApiImplicitParams({
@ApiImplicitParam(value = "页码",name = "page" ,example = "1"),
@ApiImplicitParam(value = "每页条数",name = "pageSize" ,example = "6")
})
public JsonResult<JsonPage<Order>> pageOrders(
Integer page,Integer pageSize){
// 执行分页查询的业务逻辑层
JsonPage<Order> jsonPage=orderService.getAllOrdersByPage(page,pageSize);
return JsonResult.ok("查询完成",jsonPage);
}
PageInfo对象的数据结构如下图:
**附:PageInfo全部分页信息属性**
```java
//当前页
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;
```
更多推荐
所有评论(0)