SpringBoot+PageHelper+Bootstrap+Thymeleaf 實現分頁功能

本文針對那種想要快速實現功能,而不是研究原理的,那你就直接複製我的東西,運行就好。如果想深入學習的同學請另行百度。

第一種 Spring Boot + Thymeleaf 使用PageHelper實現分頁

這種實際上就是單獨使用分頁插件來實現分頁功能。好處是,分頁條你可以自行排版,不受頁面約束。(前端使用的是thymeleaf)

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

1.1 pom.xml

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

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

1.2 application.properties

然後在springboot的application.properties配置文件中:

(本人試了一下,這些屬性可以不加,依然可以實現分頁功能。最後還是寫上吧。萬一哪天炸了呢?)

配置pageHelper分頁插件的內容:

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

1.3 UserController

想要實現功能,而不是研究怎麼搞的,你就直接複製我的東西(不建議)

/**
 *
 * @param model 攜帶數據返回
 * @param pageSize 一頁顯示多少條-非必傳值
 * @param pageNum 顯示當前頁--必傳值
 * @return 前端頁面
 * @Author: Zoutao
 * @Date: 2018/12/6
 */
//分頁查詢數據
@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();
        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));

下面對最常用的方式進行詳細介紹:

使用這種調用方式時,你可以使用RowBounds參數進行分頁,這種方式侵入性最小,我們可以看到,通過RowBounds方式調用只是使用了這個參數,並沒有增加其他任何內容。

分頁插件檢測到使用了RowBounds參數時,就會對該查詢進行物理分頁。
關於這種方式的調用,有兩個特殊的參數是針對 RowBounds 的,你可以參看上面

還有PageHelper.startPage 靜態方法調用+PageInfo的用法:代碼中的1-3步,可以放到impl層寫。反正就是在Dao層調用之前寫就可以了。

說一點:

有人說PageHelper 是不安全的分頁?
實際上PageHelper 方法使用了靜態的 ThreadLocal 參數,分頁參數和線程是綁定的。
只要你可以保證在 PageHelper 方法調用後緊跟 MyBatis 查詢方法,這就是安全的。因爲 PageHelper 在 finally 代碼段中自動清除了 ThreadLocal 存儲的對象。

1.4 Service

/**
     * 查詢所有用戶
     * @return
     */
    public List<User> getAll();

1.5 Serviceimpl

/**
     * 查詢所有用戶
     * @return
     */
    @Override
    public List<User> getAll() {
        return userMapper.getAll();
    }

1.6 Dao層/mapper

//查詢所有用戶
    @Select("SELECT * FROM tb_user")
    @ResultMap(value = "userMap")
    public List<User> getAll();

就是一個查詢所有數據的方法,然後接下來是前端頁面,我使用的thymeleaf。實際上jsp也是可以的,只不過寫的時候注意一些使用EL表達式。

1.7 前端thymeleaf頁面:

就是用來顯示分頁信息的,展示一下pageInfo的屬性,用的是BootStrap,記得引入js和css還有Bootstrap圖標或字體核心文件

<!--顯示分頁信息-->
<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/

 

 

第二種  頁神器DataTables(通用版)

下面介紹這個是DataTables表格組件,也是可以用來做分頁的。前端分頁也常用。也是需要快速實現功能的小夥伴直接複製粘貼就是。

1.後臺查詢數據

首先後臺查詢到數據,封裝到map,傳到jsp/html等頁面。

如圖:

2.前端頁面Jsp遍歷數據:

記得使用EL表達式。

可能在說的太快了,這裏分解一下。

3.在html/jsp頁面的詳細使用步驟:

在你的項目中使用 DataTables,只需要引入三個文件即可,jQuery庫,一個DT的核心js文件和一個DT的css文件,

3.1.引入1個css+2個JavaScript

源碼:

<!-- 分頁查看 -->
<link rel="stylesheet" type="text/css" href="resources/js/dataTable/jquery.dataTables.min.css">
<script type="text/javascript" src="resources/js/dataTable/jquery.js"></script>
<script type="text/javascript" src="resources/js/dataTable/jquery.dataTables.min.js"></script>

3.2.在表格的地方添加class和id屬性。(必須寫thead,tbody)

固定的class=“tablelist” id=“example”
源碼:

<table cellspacing="0px" cellpadding="0px" border="1px" width="100%" class="tablelist" id="example">
			<thead>
				<tr>
					<th>課程ID</th>
					<th>課程名</th>
					<th>方向</th>
					<th>描述</th>
					<th>時長(小時)</th>
					<th>操作人</th>
				</tr>
			</thead>
			
<tbody>
				<c:forEach items="${cList }" var="course">
					<tr>
						<td>${course.courseId }</td>
						<td>${course.courseName }</td>
						<td>${course.courseType }</td>
						<td>${course.description }</td>
						<td>${course.courseTime }</td>
						<td>${course.operator }</td>
					</tr>
				</c:forEach>
			</tbody>
		</table>

3.3.添加分頁的script即可。

 

<script type="text/javascript">
		$(document).ready(function(){
			$("#example").dataTable({
				 "bProcessing" : true, //DataTables載入數據時,是否顯示‘進度’提示
				 "aLengthMenu" : [5, 10, 15], //更改顯示記錄數選項
				 "sPaginationType" : "full_numbers", //詳細分頁組,可以支持直接跳轉到某頁
				 "bAutoWidth" : true, //是否自適應寬度
				 //"bJQueryUI" : true,
				 "oLanguage": { //國際化配置  
		                "sProcessing" : "正在獲取數據,請稍後...",    
		                "sLengthMenu" : "顯示 _MENU_ 條",    
		                "sZeroRecords" : "沒有您要搜索的內容",    
		                "sInfo" : "從 _START_ 到  _END_ 條記錄 總記錄數爲 _TOTAL_ 條",    
		                "sInfoEmpty" : "記錄數爲0",    
		                "sInfoFiltered" : "(全部記錄數 _MAX_ 條)",    
		                "sInfoPostFix" : "",    
		                "sSearch" : "搜索",    
		                "sUrl" : "",    
		                "oPaginate": {    
		                    "sFirst" : "第一頁",    
		                    "sPrevious" : "上一頁",    
		                    "sNext" : "下一頁",    
		                    "sLast" : "最後一頁"    
		                }  
		            },  
		    });
		});
	</script>

其他可以參考官網:http://www.datatables.club/example/diy.html

一些屬性參數說明:

默認情況下 Datatables 的分頁就是上一頁、下一頁和6個頁數按鈕,這適合大部分情況。
不過也有用戶不喜歡這樣,Datatables提供了四個模式供用戶選擇,通過設置pagingType選項來配置。

  1. numbers - 只有只有數字按鈕
  2. simple - 只有上一頁、下一頁兩個按鈕
  3. simple_numbers - 除了上一頁、下一頁兩個按鈕還有頁數按鈕,Datatables默認是這個
  4. full - 有四個按鈕首頁、上一頁、下一頁、末頁
  5. full_numbers - 除首頁、上一頁、下一頁、末頁四個按鈕還有頁數按鈕
  6. first_last_numbers - 除首頁、末頁兩個按鈕還有頁數按鈕

還有一些常用操作:

1.開啓水平滾動條,設置scrollX選項 加入css樣式 th, td { white-space: nowrap; } ,使文字內容在一行裏,實現動態高度。

2.通常你可能會想要你的表格跟着頁面大小的變化而變化。下面的例子展示了,表格設置了width爲100%,表格隨着頁面的大小變化自動適應。 Tips:試着改變瀏覽器窗口的大小看看效果

3.可以使用language選項來國際化Datatables的相關信息

3.4.點擊行獲取數據:

(多寫的取值例子,爲了方便小夥伴們)

$(document).ready(function() {
    var table = $('#example').DataTable();
    $('#example tbody').on('click', 'tr', function () {
        var data = table.row( this ).data();
        alert( 'You clicked on '+data[0]+'\'s row' );
    } );
} );

直接複製粘貼過去即可實現分頁效果,而且還帶有查詢等功能。

DataTables 默認情況已啓用一些功能,搜索、 排序、 分頁等功能已經開啓。

最後效果如下:

上面就說完了這一種使用DataTables的分頁方式。需要快速實現功能的,你就複製粘貼吧。
也需要引入對應css、js的。
需要的可以官網下載或者留下郵箱我發給你。

 

第三種 使用Bootstrap Table表格分頁

JavaScript 表格控件可以操作大數據集的 HTML表格,提供各種功能,如分頁、排序、過濾以及行編輯。
比如最常用的3款:

  1. datatables:http://www.datatables.club/
  2. Bootstra Table:http://bootstrap-table.wenzhixin.net.cn/zh-cn/home/
  3. EasyU DataGrid: http://www.jeasyui.net/plugins/183.html

使用步驟:

1.Html中聲明table

<table id="table"></table>

2.Jquery中初始化bootstrap table:

源碼如下:

<script>
    var $table = $('#table');
        // bootstrap table初始化
        // http://bootstrap-table.wenzhixin.net.cn/zh-cn/documentation/
        $table.bootstrapTable({
            url: '/listUser',
            height: getHeight(),
            striped: true, //設置爲 true 會有隔行變色效果
            undefinedText: "數據爲空",//當數據爲 undefined 時顯示的字符
            search: true,
            searchOnEnterKey: true,
            showRefresh: true,
            showToggle: true,//是否顯示切換試圖(table/card)按鈕
            showColumns: true,//是否顯示 內容列下拉框
            // showPaginationSwitch:true,//是否顯示 數據條數選擇框
            minimumCountColumns: 2,
            showPaginationSwitch: true,
            clickToSelect: true,
            detailView: true,
            detailFormatter: 'detailFormatter',
            pagination: true,//分頁
            pageSize: 8, //如果設置了分頁,頁面數據條數
            pageList: [5, 10, 20, 40], //如果設置了分頁,設置可供選擇的頁面數據條數。設置爲All 則顯示所有記錄。
            paginationLoop: false,//設置爲 true 啓用分頁條無限循環的功能
            // singleSelect: false,//設置True 將禁止多選
            data_local: "zh-US",//表格漢
            search: true, //顯示搜索框
            classes: 'table table-hover table-no-bordered',
            //sidePagination: 'server',
            //silentSort: false,
            smartDisplay: false,
            idField: 'id', //指定主鍵列
            sortName: 'id',
            sortOrder: 'desc',
            escape: true,
            searchOnEnterKey: true,
            idField: 'systemId',
            maintainSelected: true,
            toolbar: '#toolbar',
            columns: [
                {field: 'state', checkbox: true},
                {field: 'realname', title: '真實姓名', sortable: true, halign: 'center'},
                {field: 'username', title: '賬號', sortable: true, halign: 'center'},
                {field: 'password', title: '密碼', sortable: true, halign: 'center'},
                {field: 'address', title: '地址', sortable: true, halign: 'center'},
                {field: 'createtime', title: '創建時間', sortable: true, halign: 'center'},
                {field: 'action', title: '操作', halign: 'center', align: 'center', formatter: 'actionFormatter', events: 'actionEvents', clickToSelect: false}
            ]
        }).on('all.bs.table', function (e, name, args) {
            $('[data-toggle="tooltip"]').tooltip();
            $('[data-toggle="popover"]').popover();
        });
    });

3.後臺:查詢數據,返回json字符串

必須返回json字符串或json對象

@ResponseBody
@RequestMapping(value = "listUser", method = RequestMethod.GET)
public String listUser(HttpServletRequest request, HttpServletResponse response) {
    List<User> userList = userService.getAll();
    System.out.println("分頁數據:" + userList);
    return JSON.toJSONString(userList);
}

效果圖如下

自帶pagination分頁:

模糊查詢:

都是需要引入js、css等的,但是這些都是可以在官網上下載的,我就不貼出來了。主要是代碼,你可以在複製過去直接使用,免得以後做項目還得重新寫分頁,麻煩。

**多種不同的分頁方式就寫完了,實際上,thymeleaf適用的,jsp、 html頁面都可以適用。照着文章複製去用即可。**

 

原文鏈接:https://blog.csdn.net/ITBigGod/article/details/85224897

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章