先知道怎么手写一个分页查询,再去使用 PageHelper 吧
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 方法 用于分页查询,具体包含:
页码总数 totalPage 的计算
页码列表的容错处理。比如总页码只有 8 页,但是我们在地址栏手动修改为 12 页,我们需要它在分页栏高亮最后一页并显示最后一页数据,而不是第 12 页,第 12 页是不存在的。
分页查询数据。涉及每页起始索引的计算
第 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 pageSize 每页显示的问题数量
@return*/public PaginationDTO list(Integer pageNumber, Integer pageSize) {
PaginationDTO paginationDTO = new PaginationDTO();Integer totalCount = questionMapper.count(); // 问题总数 Integer totalPage; // 页码总数
// 计算页码总数 if (totalCount % pageSize == 0) {totalPage = totalCount / pageSize;}else {totalPage = totalCount / pageSize + 1;}
// 页码列表的容错处理 if (pageNumber < 1) {pageNumber = 1;}if(pageNumber > totalPage) {pageNumber = totalPage;}
paginationDTO.setPagination(totalPage, pageNumber);
Integer offset = pageSize * (pageNum
ber - 1); // 每页的起始索引 List<Question> questions = questionMapper.list(offset, pageSize); // 分页查询当前页的具体数据 paginationDTO.setQuestionList(questions); // 存储当前页的具体数据 return paginationDTO;}}
对应的 MyBatis 的 mapper 文件 QuestionMapper 如下:
@Select("select * from question limit #{offset}, #{pageSize}")List<Question> list(@Param("offset") Integer offset, @Param("pageSize") Integer pageSize);
MyBatis 约定当我们传入的参数不是实体类对象的时候,需要利用 @Param 自己完成映射
评论