写点什么

先知道怎么手写一个分页查询,再去使用 PageHelper 吧

  • 2021 年 11 月 11 日
  • 本文字数:2082 字

    阅读完需:约 7 分钟

select * from tableName limit offset size


这条语句的含义是:从 tableName 表中的第 offset 条记录开始(注意 offset 从零开始),查询出 size 个记录。


举个例子,category 表中数据如下:



运行下边这条语句:查询从第 2 条记录(即 id = 3)开始的连续 5 条记录


select * from category limit 2, 5;


3. 承载分页信息的实体类

分页信息实体类包含如下数据:


  • 是否显示上一页按钮 showPrevious

  • 是否显示下一页按钮 showNext

  • 是否显示跳转到第一页按钮 showFirstPage

  • 是否显示跳转到最后一页按钮 showEndPage

  • 当前页码 pageNumber

  • 当前页可跳转的页码列表 pageNumbers

  • 总页码数 totalPage

  • 当前页要显示的具体数据


/**


  • 分页所需要的信息*/public class PaginationDTO {private boolean showPrevious; // 是否显示上一页按钮 private boolean showNext; // 是否显示下一页按钮 private boolean showFirstPage; // 是否显示跳转到第一页按钮 private boolean showEndPage; // 是否显示跳转到最后一页按钮


private Integer pageNumber; // 当前页码 private List<Integer> pageNumbers = new ArrayList<>(); // 当前页可跳转的页码列表 private Integer totalPage; // 总页码数


private List<Question> questionList; // 当前页要显示的具体数据


// Getter and Setter

4. 根据当前页码设置分页所需要的信息

这段代码做的事情就是我们在第 1 节分析的,决定上一页、下一页、第一页和最后一页按钮是否显示。


显然,这段代码应该放在承载分页信息的实体类 PaginationDTO 中:


/**


  • 分页所需要的信息*/@Datapublic class PaginationDTO {


......


/**


  • 根据当前页码设置相关分页信息

  • @param totalPage 页码总数

  • @param pageNumber 当前页码*/public void setPagination(Integer totalPage, Integer pageNumber) {this.totalPage = totalPage;this.pageNumber = pageNumber;


// 页码列表的显示:显示当前页和当前页的前三页和后三页,可为空 pageNumbers.add(pageNumber);for (int i = 1; i <= 3; i++) {if (pageNumber - i > 0) {pageNumbers.add(0, pageNumber - i);}


if (pageNumber + i <= totalPage) {pageNumbers.add(pageNumber + i);}}


// 是否展示上一页按钮 if (pageNumber == 1) {showPrevious = false;}else {showPrevious = true;}// 是否展示下一页按钮 if (pageNumber.equals(totalPage)) {showNext = false;}else {showNext = true;}


// 是否展示跳转到第一页按钮 if (pageNumbers.contains(1)) {// 如果当前页可跳转的页码列表包含第一页,则不展示跳转到第一页按钮 showFirstPage = false;}else {showFirstPage = true;}// 是否展示跳转到最后一页按钮 if (pageNumbers.contains(totalPage)) {// 如果当前页可跳转的页码列表包含最后一页,则不展示跳转到最后一页按钮 showEndPage = false;}else {showEndPage = true;}}}

5. 分页查询请求入口

Controller 层:


@Controllerpublic class IndexController {


@Autowiredprivate QuestionService questionService;


/**


  • @param request

  • @param model

  • @param pageNumber 第多少页,默认第 1 页

  • @param pageSize 每页显示的问题数量, 默认为 10

  • @return*/@GetMapping("/")public String index(HttpServletRequest request, Model model,@RequestParam(name = "pageNumber", defaultValue = "1") Integer pageNumber,@RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize) {


.........


// 获取问题列表需要的信息 PaginationDTO pagination = questionService.list(pageNumber, pageSize);model.addAttribute("pagination", pagination);


......}}


对应的前端:(Thymeleaf 模板引擎),利用 th:each 标签循环页码列表,然后在 url 后面加上 pageNumber,使得后端能够通过 RequestParam 获取到当前页码


<li th:each="pageNumber : {pagination.pageNumber == pageNumber}? 'active' : ''"><a th:href="@{/(pageNumber = {pageNumber})}" th:text="{pageNumber}"></a></li>


上一页、下一页、第一页和最后一页按钮的前端代码就不贴了,大同小异。


QuestionService 如下

6. 分页查询

前面说过,页面承载的信息是 Question,我们建立一个 QuestionService.list 方法 用于分页查询,具体包含:


  1. 页码总数 totalPage 的计算

  2. 页码列表的容错处理。比如总页码只有 8 页,但是我们在地址栏手动修改为 12 页,我们需要它在分页栏高亮最后一页并显示最后一页数据,而不是第 12 页,第 12 页是不存在的。



  1. 分页查询数据。涉及每页起始索引的计算


  • 第 1 页:起始索引 0,limit 0, 10

  • 第 2 页:起始索引 10,limit 10, 20

  • 第 3 页:起始索引 30,limit 20, 30

  • ......


推出 => 若当前页码为 i,每页显示 10 条数据,则每页的起始索引 offset = 10 * (i - 1)


@Servicepublic class QuestionService {


@Autowiredprivate QuestionMapper questionMapper;


/**


  • 分页查询

  • @param pageNumber 第多少页(当前页码)

  • @param pageSiz


【一线大厂Java面试题解析+后端开发学习笔记+最新架构讲解视频+实战项目源码讲义】
浏览器打开:qq.cn.hn/FTf 免费领取
复制代码


e 每页显示的问题数量


  • @return*/

评论

发布
暂无评论
先知道怎么手写一个分页查询,再去使用PageHelper吧