天天看點

SpringMvc+Mybatis+Pagehelper分頁詳解

最近公司需要做一個告警頁面的功能,需要分頁,查了很多資料發現PageHelper比較合适

故寫一篇從零開始的PageHelper使用的教程,也記錄下忙活一天的東西

1.首先需要在項目中添加PageHelper的依賴,這裡我用的Maven添加

<dependency>
  <groupId>com.github.pagehelper</groupId>
  <artifactId>pagehelper</artifactId>
  <version>4.1.6</version>
</dependency>
           

2.在mybatis的配置檔案中添加對pagehelper 的配置

<configuration>    
    <plugins>  
        <!-- com.github.pagehelper為PageHelper類所在包名 -->  
        <plugin interceptor="com.github.pagehelper.PageHelper">  
            <!-- 4.0.0以後版本可以不設定該參數 -->  
            <property name="dialect" value="mysql"/>  
            <!-- 該參數預設為false -->  
            <!-- 設定為true時,會将RowBounds第一個參數offset當成pageNum頁碼使用 -->  
            <!-- 和startPage中的pageNum效果一樣-->  
            <property name="offsetAsPageNum" value="true"/>  
            <!-- 該參數預設為false -->  
            <!-- 設定為true時,使用RowBounds分頁會進行count查詢 -->  
            <property name="rowBoundsWithCount" value="true"/>  
            <!-- 設定為true時,如果pageSize=0或者RowBounds.limit = 0就會查詢出全部的結果 -->  
            <!-- (相當于沒有執行分頁查詢,但是傳回結果仍然是Page類型)-->  
            <property name="pageSizeZero" value="true"/>  
            <!-- 3.3.0版本可用 - 分頁參數合理化,預設false禁用 -->  
            <!-- 啟用合理化時,如果pageNum<1會查詢第一頁,如果pageNum>pages會查詢最後一頁 -->  
            <!-- 禁用合理化時,如果pageNum<1或pageNum>pages會傳回空資料 -->  
            <property name="reasonable" value="true"/>  
            <!-- 3.5.0版本可用 - 為了支援startPage(Object params)方法 -->  
            <!-- 增加了一個`params`參數來配置參數映射,用于從Map或ServletRequest中取值 -->  
            <!-- 可以配置pageNum,pageSize,count,pageSizeZero,reasonable,orderBy,不配置映射的用預設值 -->  
            <!-- 不了解該含義的前提下,不要随便複制該配置 -->  
            <!-- <property name="params" value="pageNum=start;pageSize=limit;"/> -->  
            <!-- 支援通過Mapper接口參數來傳遞分頁參數 -->  
            <property name="supportMethodsArguments" value="true"/>  
            <!-- always總是傳回PageInfo類型,check檢查傳回類型是否為PageInfo,none傳回Page -->  
            <property name="returnPageInfo" value="check"/>  
        </plugin>  
    </plugins>  
</configuration>
           

3.添加一個PageBean的類來儲存分頁的資訊

public class PageBean<T> implements Serializable  {
	 private static final long serialVersionUID = 1L;
	    private long total; //總記錄數
	    private List<T> list; //結果集
	    private int pageNum; //第幾頁
	    private int pageSize; //每頁記錄數
	    private int pages; // 總頁數
	    private int size; //目前頁的數量<=pageSize

	    public PageBean(List<T> list){
	        if (list instanceof Page){
	            Page<T> page = (Page<T>) list;
	            this.pageNum = page.getPageNum();
	            this.pageSize = page.getPageSize();
	            this.total = page.getTotal();
	            this.pages = page.getPages();
	            this.list = page;
	            this.size = page.size();
	        }
	    }
	    public long getTotal() {
	        return total;
	    }
	    public void setTotal(long total) {
	        this.total = total;
	    }
	    public List<T> getList() {
	        return list;
	    }

	    public void setList(List<T> list) {
	        this.list = list;
	    }
	    public int getSize() {
	        return size;
	    }
	    public void setSize(int size) {
	        this.size = size;
	    }
	    public int getPageNum() {
	        return pageNum;
	    }
	    public void setPageNum(int pageNum) {
	        this.pageNum = pageNum;
	    }
	    public int getPageSize() {
	        return pageSize;
	    }

	    public void setPageSize(int pageSize) {
	        this.pageSize = pageSize;
	    }
	    public int getPages() {
	        return pages;
	    }
	    public void setPages(int pages) {
	        this.pages = pages;
	    }
	}

           

下面就是業務邏輯的代碼了

4.首先從mapper.xml檔案寫起,操作資料庫的sql,查出我們所需要的資料

<select id="selectallList" parameterType="com.alarm.bean.AlarmParamModel"
		resultMap="AlarmMap">
		select message_id, seqnum, message_type, process_status,
		distribute_status, processor, occur_time, close_time, 
		system_id, group_id, warn_level, message_content
		from td_alarm_info
	</select>
           

5.mapper的接口方法

public List<AlarmParamModel> selectallList(AlarmParamModel model);
           

6.service的接口方法

Datagrid selectallList(AlarmParamModel model,int pageNum, int pageSize);
           

7.service的實作類

   這裡需要注意下,是分頁的主要邏輯。pageNum表示頁碼,pageSize表示每頁顯示的數目,startPag方法是初始的頁面,orderBy方法是将資料按某個字段進行排序,這裡我用的是occr_time的降序(desc)

public Datagrid selectallList(AlarmParamModel model,int pageNum, int pageSize){
		PageHelper.startPage(pageNum, pageSize);
		PageHelper.orderBy("occur_time desc");
		 List<AlarmParamModel> list = this.alarmMgrMapper.selectallList(model);
		 PageInfo<AlarmParamModel> pageInfo = new PageInfo<AlarmParamModel>(list);
		Datagrid datagrid = new Datagrid(pageInfo.getTotal(),pageInfo.getList());
	      return datagrid;
	}
           

8.注意到我這邊用了一個Datagrid類,是用于向前台傳資料用的類,包括total(總數)和rows(資料)

public class Datagrid {
	private long total;
	private List rows = new ArrayList<>();
	
	public Datagrid() {
		super();
	}
	
	public Datagrid(long total, List rows) {
		super();
		this.total = total;
		this.rows = rows;
	}

	public long getTotal() {
		return total;
	}

	public void setTotal(long total) {
		this.total = total;
	}

	public List getRows() {
		return rows;
	}

	public void setRows(List rows) {
		this.rows = rows;
	}

}
           

9.開始寫controller層,調用之前寫的方法

  這裡需要注意的是,offset和limit 是前台傳來的頁碼和每頁顯示的數量,差別于bootstraptable 的offset和limit,那個offset表示的是偏移量,即如果每頁顯示10條資料,那麼bootstrap中的第二頁表示的offset就是10,第一頁和第三頁分别是0和20。而我這裡的offset就是指代的pageNum。

@RequestMapping(value = "/AlarmInfo/list", method = {RequestMethod.GET,RequestMethod.POST})
	@ResponseBody
	public Datagrid alarmInfo(AlarmParamModel model,@RequestParam(value="offset",defaultValue="0",required=false)Integer pageNum, 
			@RequestParam(value="limit",defaultValue="10",required=false)Integer pageSize) 
	{
		Datagrid datagrid = this.alarmMgrService.selectallList(model,pageNum, pageSize);
        return datagrid;
	}
           

10. 到現在前台的請求已經可以擷取背景的資料并且分頁了,我再将我的前台bootstrap table 的配置貼一下

$('#tb_departments').bootstrapTable({
            url: 'http://10.1.234.134:8088/api/AlarmInfo/list',         //請求背景的URL(*)
            method: 'get',                      //請求方式(*)
            striped: false,                      //是否顯示行間隔色
            cache: false,                       //是否使用緩存,預設為true,是以一般情況下需要設定一下這個屬性(*)
            pagination: true,                   //是否顯示分頁(*)
            onlyInfoPagination:true,			//設定為 true 隻顯示總資料數,而不顯示分頁按鈕。需要 pagination='True'
            sortable: true,                     //是否啟用排序
            sortOrder: "asc",                   //排序方式
            queryParams: oTableInit.queryParams,//傳遞參數(*)
            sidePagination: "server",           //分頁方式:client用戶端分頁,server服務端分頁(*)
            pageNumber:1,                       //初始化加載第一頁,預設第一頁
            pageSize: 10,                       //每頁的記錄行數(*)
            pageList: [10, 25, 50, 100],        //可供選擇的每頁的行數(*)
            search: false,                       //是否顯示表格搜尋,此搜尋是用戶端搜尋,不會進服務端,是以,個人感覺意義不大
            strictSearch: true,
            showColumns: false,                  //是否顯示所有的列
            showRefresh: false,                  //是否顯示重新整理按鈕
            minimumCountColumns: 2,             //最少允許的列數
            clickToSelect: true,                //是否啟用點選選中行
            checkboxHeader:true,				//add
            height: 500,                        //行高,如果沒有設定height屬性,表格自動根據記錄條數覺得表格高度
            uniqueId: "id",                     //每一行的唯一辨別,一般為主鍵列
            showToggle:false,                    //是否顯示詳細視圖和清單視圖的切換按鈕
            cardView: false,                    //是否顯示詳細視圖
            detailView: true,
            detailFormatter:detailFormatter ,
            paginationHAlign:"left",
            paginationDetailHAlign:"right",
           

這裡我沒有用bootstrap自帶的分頁按鈕,我是自己用jq寫的按鈕組,在下一篇文章我會把按鈕代碼貼出來,這樣可自定義的程度會高一些~  你也可以直接用bootstraptable子帶的分頁按鈕,把配置改下就好。

偷偷cx的人記住hkf是你們爸爸