天天看點

Spring Boot + Thymeleaf 使用PageHelper實作分頁

一、概述

使用分頁插件來實作分頁功能。好處是,分頁條你可以自行排版,不受頁面限制。(前端使用的是thymeleaf)

我使用的是spring boot 2.1.11.RELEASE,如果按照以下步驟不能實作分頁,那可能是pagehelper的版本問題,更換版本試一下。

二、使用

首先在項目pom.xml中加入pagehelper插件的依賴

<!--pagehelper分頁插件 -->
<dependency>
   <groupId>com.github.pagehelper</groupId>
   <artifactId>pagehelper-spring-boot-starter</artifactId>
   <version>1.2.5</version>
</dependency>      

配置

pagehelper.helper-dialect=mysql
pagehelper.reasonable=true
pagehelper.support-methods-arguments=true
pagehelper.params=count=countSql      

controller

//分頁查詢資料
@GetMapping("/usermanage")
public String usermanage(Model model,
                         @RequestParam(required = false,defaultValue="1",value="pageNum")Integer pageNum,
                         @RequestParam(defaultValue="5",value="pageSize")Integer pageSize){
 
    //為了程式的嚴謹性,判斷非空:
    if(pageNum == null){
        pageNum = 1;   //設定預設目前頁
    }
    if(pageNum <= 0){
        pageNum = 1;
    }
    if(pageSize == null){
        pageSize = 5;    //設定預設每頁顯示的資料數
    }
    System.out.println("目前頁是:"+pageNum+"顯示條數是:"+pageSize);
 
    //1.引入分頁插件,pageNum是第幾頁,pageSize是每頁顯示多少條,預設查詢總數count
    PageHelper.startPage(pageNum,pageSize);
    //2.緊跟的查詢就是一個分頁查詢-必須緊跟.後面的其他查詢不會被分頁,除非再次調用PageHelper.startPage
    try {
        List<User> userList = userService.getAll();//service查詢所有的資料的接口
        System.out.println("分頁資料:"+userList);
        //3.使用PageInfo包裝查詢後的結果,5是連續顯示的條數,結果list類型是Page<E>
        PageInfo<User> pageInfo = new PageInfo<User>(userList,pageSize);
        //4.使用model/map/modelandview等帶回前端
        model.addAttribute("pageInfo",pageInfo);
    }finally {
        PageHelper.clearPage(); //清理 ThreadLocal 存儲的分頁參數,保證線程安全
    }
    //5.設定傳回的jsp/html等前端頁面
    // thymeleaf預設就會拼串classpath:/templates/xxxx.html
    return "admin/user/list";
}      

重要提示:

  1. 隻有緊跟在PageHelper.startPage()方法後的第一個Mybatis的查詢(Select)方法會被分頁。
  2. 請不要在系統中配置多個分頁插件(使用Spring時,mybatis-config.xml和Spring配置方式,請選擇其中一種,不要同時配置多個分頁插件)!
  3. 對于帶有for update的sql,會抛出運作時異常,對于這樣的sql建議手動分頁,畢竟這樣的sql需要重視。
  4. 由于嵌套結果方式會導緻結果集被折疊,是以分頁查詢的結果在折疊後總數會減少,是以無法保證分頁結果數量正确。

還有就分頁插件支援以下幾種調用方式(你任選),複制粘貼就好: 

//第一種,RowBounds方式的調用
List<Country> list = sqlSession.selectList("x.y.selectIf", null, new RowBounds(0, 10));
 
//第二種,Mapper接口方式的調用,推薦這種使用方式。
PageHelper.startPage(1, 10);
List<Country> list = countryMapper.selectIf(1);
 
//第三種,Mapper接口方式的調用,推薦這種使用方式。
PageHelper.offsetPage(1, 10);
List<Country> list = countryMapper.selectIf(1);
 
//第四種,參數方法調用
//存在以下 Mapper 接口方法,你不需要在 xml 處理後兩個參數
public interface CountryMapper {
    List<Country> selectByPageNumSize(
            @Param("user") User user,
            @Param("pageNum") int pageNum,
            @Param("pageSize") int pageSize);
}
//配置supportMethodsArguments=true
//在代碼中直接調用:
List<Country> list = countryMapper.selectByPageNumSize(user, 1, 10);
 
//第五種,參數對象
//如果 pageNum 和 pageSize 存在于 User 對象中,隻要參數有值,也會被分頁
//有如下 User 對象
public class User {
    //其他fields
    //下面兩個參數名和 params 配置的名字一緻
    private Integer pageNum;
    private Integer pageSize;
}
//存在以下 Mapper 接口方法,你不需要在 xml 處理後兩個參數
public interface CountryMapper {
    List<Country> selectByPageNumSize(User user);
}
//當 user 中的 pageNum!= null && pageSize!= null 時,會自動分頁
List<Country> list = countryMapper.selectByPageNumSize(user);
 
//第六種,ISelect 接口方式
//jdk6,7用法,建立接口
Page<Country> page = PageHelper.startPage(1, 10).doSelectPage(new ISelect() {
    @Override
    public void doSelect() {
        countryMapper.selectGroupBy();
    }
});
//jdk8 lambda用法
Page<Country> page = PageHelper.startPage(1, 10).doSelectPage(()-> countryMapper.selectGroupBy());
 
//也可以直接傳回PageInfo,注意doSelectPageInfo方法和doSelectPage
pageInfo = PageHelper.startPage(1, 10).doSelectPageInfo(new ISelect() {
    @Override
    public void doSelect() {
        countryMapper.selectGroupBy();
    }
});
//對應的lambda用法
pageInfo = PageHelper.startPage(1, 10).doSelectPageInfo(() -> countryMapper.selectGroupBy());
 
//count查詢,傳回一個查詢語句的count數
long total = PageHelper.count(new ISelect() {
    @Override
    public void doSelect() {
        countryMapper.selectLike(country);
    }
});
//lambda
total = PageHelper.count(()->countryMapper.selectLike(country));      

前端thmeleaf

<!--顯示分頁資訊-->
<div class="modal-footer no-margin-top">
    <div class="col-md-6">
        目前第 [[${pageInfo.pageNum}]]頁,共 [[${pageInfo.pages}]] 頁.一共 [[${pageInfo.total}]] 條記錄
    </div>
 
    <ul class="pagination pull-right no-margin">
        <li th:if="${pageInfo.hasPreviousPage}">
            <a th:href="'/usermanage?pageNum=1'">首頁</a>
        </li>
 
        <li class="prev" th:if="${pageInfo.hasPreviousPage}">
            <a th:href="'/usermanage?pageNum='+${pageInfo.prePage}">
                <i class="ace-icon fa fa-angle-double-left"></i>
            </a>
        </li>
        <!--周遊條數-->
            <li th:each="nav:${pageInfo.navigatepageNums}">
                <a th:href="'/usermanage?pageNum='+${nav}" th:text="${nav}" th:if="${nav != pageInfo.pageNum}"></a>
                <span style="font-weight: bold;background: #6faed9;" th:if="${nav == pageInfo.pageNum}" th:text="${nav}" ></span>
            </li>
 
        <li class="next" th:if="${pageInfo.hasNextPage}">
            <a th:href="'/usermanage?pageNum='+${pageInfo.nextPage}">
                <i class="ace-icon fa fa-angle-double-right"></i>
            </a>
        </li>
 
        <li>
            <a th:href="'/usermanage?pageNum='+${pageInfo.pages}">尾頁</a>
        </li>
    </ul>
</div>
 
<div>目前頁号:<span th:text="${pageInfo.pageNum}"></span></div>
<div>每頁條數:<span th:text="${pageInfo.pageSize}"></span></div>
<div>起始行号:<span th:text="${pageInfo.startRow}"></span></div>
<div>終止行号:<span th:text="${pageInfo.endRow}"></span></div>
<div>總結果數:<span th:text="${pageInfo.total}"></span></div>
<div>總頁數:<span th:text="${pageInfo.pages}"></span></div>
<hr />
<div>是否為第一頁:<span th:text="${pageInfo.isFirstPage}"></span></div>
<div>是否為最後一頁:<span th:text="${pageInfo.isLastPage}"></span></div>
<div>是否有前一頁:<span th:text="${pageInfo.hasPreviousPage}"></span></div>
<div>是否有下一頁:<span th:text="${pageInfo.hasNextPage}"></span></div>