Spring Boot + Thymeleaf 使用PageHelper實現分頁
阿新 • • 發佈:2020-12-24
技術標籤:# Springboot2企業級開發
一、概述
使用分頁外掛來實現分頁功能。好處是,分頁條你可以自行排版,不受頁面約束。(前端使用的是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"; }
重要提示:
- 只有緊跟在PageHelper.startPage()方法後的第一個Mybatis的查詢(Select)方法會被分頁。
- 請不要在系統中配置多個分頁外掛(使用Spring時,mybatis-config.xml和Spring配置方式,請選擇其中一種,不要同時配置多個分頁外掛)!
- 對於帶有for update的sql,會丟擲執行時異常,對於這樣的sql建議手動分頁,畢竟這樣的sql需要重視。
- 由於巢狀結果方式會導致結果集被摺疊,因此分頁查詢的結果在摺疊後總數會減少,所以無法保證分頁結果數量正確。
還有就分頁外掛支援以下幾種呼叫方式(你任選),複製貼上就好:
//第一種,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>
這是使用的thymeleaf語法來整合PageHelper實現的分頁,很多從JSP轉thymeleaf的同學可以直接使用這個程式碼就好了。
說明一點哈,這些都是需要引入CSS,js,jquery之類的,基本上版本通用的,PageHelper官網就有,不要不引入就來跟我說沒有效果。
PageHelper官網:https://pagehelper.github.io/docs/howtouse/