1. 程式人生 > >Mybatis的外掛 PageHelper 分頁查詢使用方法

Mybatis的外掛 PageHelper 分頁查詢使用方法

Mybatis的一個外掛,PageHelper,非常方便mybatis分頁查詢。國內牛人的一個開源專案,有興趣的可以去看原始碼,都有中文註釋(ps:某些原始碼一大堆英文,痛哭流涕!)

它支援基本主流與常用的資料庫,這可以在它的文件上看到。這裡記錄一下使用的基本方法

0.檢視文件與使用準備

開發文件有中文文件也有英文文件




1.配置攔截器外掛


這個是配置在mybatis-config.xml檔案中

文件中的示例:

<!-- 
    plugins在配置檔案中的位置必須符合要求,否則會報錯,順序如下:
    properties?, settings?, 
    typeAliases?, typeHandlers?, 
    objectFactory?,objectWrapperFactory?, 
    plugins?, 
    environments?, databaseIdProvider?, mappers?
-->
<plugins>
    <!-- com.github.pagehelper為PageHelper類所在包名 -->
    <plugin interceptor="com.github.pagehelper.PageInterceptor">
        <!-- 使用下面的方式配置引數,後面會有所有的引數介紹 -->
        <property name="param1" value="value1"/>
	</plugin>
</plugins>

我的配置:

    <plugins>
        <plugin interceptor="com.github.pagehelper.PageInterceptor">
            <!-- config params as the following -->
            <!--<!–分頁引數合理化  –>-->
            <property name="reasonable" value="true"/>
        </plugin>
    </plugins>

一些配置引數的說明可以參考文件: 【分頁外掛引數介紹】

這裡就說明一下reasonable的配置:

reasonable:分頁合理化引數,預設值為false。當該引數設定為 true 時,pageNum<=0 時會查詢第一頁,pageNum>pages(超過總數時),會查詢最後一頁。預設false 時,直接根據引數進行查詢。

那麼如何選擇這些配置引數,文件中也給出了詳細說明:【如何選擇配置這些引數】

2.在程式碼中使用

官方文件也有這部分說明和案例,那麼我就以自己的使用案例

    @RequestMapping("/emps")
    public String list(@RequestParam(required = false,defaultValue = "1",value = "pn")Integer pn,
                       Map<String,Object> map){

        //引入分頁查詢,使用PageHelper分頁功能
        //在查詢之前傳入當前頁,然後多少記錄
        PageHelper.startPage(pn,5);
        //startPage後緊跟的這個查詢就是分頁查詢
        List<Employee> emps = employeeService.getAll();
        //使用PageInfo包裝查詢結果,只需要將pageInfo交給頁面就可以
        PageInfo pageInfo = new PageInfo<>(emps,5);
        //pageINfo封裝了分頁的詳細資訊,也可以指定連續顯示的頁數

        map.put("pageInfo",pageInfo);
        return "list";
    }

以上使用說明:

·在查詢呼叫方法前宣告分頁資訊(當前頁,每頁記錄數)

·在查詢呼叫方法對查詢結果進行包裝成PageInfo物件,也可以是定連續顯示的頁數,這也是常用功能。

注意:都是與查詢方法緊挨著的,不要中間夾雜其它無關語句

之後把資訊放在ModelAndView中就可以在前臺訪問了。

下面說一下為什麼要把查詢結果包裝成PageInfo物件

3.PageInfo類說明


類原始碼(更多原始碼去github上檢視即可):

public class PageInfo<T> implements Serializable {
    private static final long serialVersionUID = 1L;
    //當前頁
    private int pageNum;
    //每頁的數量
    private int pageSize;
    //當前頁的數量
    private int size;

    //由於startRow和endRow不常用,這裡說個具體的用法
    //可以在頁面中"顯示startRow到endRow 共size條資料"

    //當前頁面第一個元素在資料庫中的行號
    private int startRow;
    //當前頁面最後一個元素在資料庫中的行號
    private int endRow;
    //總記錄數
    private long total;
    //總頁數
    private int pages;
    //結果集
    private List<T> list;

    //前一頁
    private int prePage;
    //下一頁
    private int nextPage;

    //是否為第一頁
    private boolean isFirstPage = false;
    //是否為最後一頁
    private boolean isLastPage = false;
    //是否有前一頁
    private boolean hasPreviousPage = false;
    //是否有下一頁
    private boolean hasNextPage = false;
    //導航頁碼數
    private int navigatePages;
    //所有導航頁號
    private int[] navigatepageNums;
    //導航條上的第一頁
    private int navigateFirstPage;
    //導航條上的最後一頁
    private int navigateLastPage;

    public PageInfo() {
    }

    /**
     * 包裝Page物件
     *
     * @param list
     */
    public PageInfo(List<T> list) {
        this(list, 8);
    }

    /**
     * 包裝Page物件
     *
     * @param list          page結果
     * @param navigatePages 頁碼數量
     */
    public PageInfo(List<T> list, int navigatePages) {
        if (list instanceof Page) {
            Page page = (Page) list;
            this.pageNum = page.getPageNum();
            this.pageSize = page.getPageSize();

            this.pages = page.getPages();
            this.list = page;
            this.size = page.size();
            this.total = page.getTotal();
            //由於結果是>startRow的,所以實際的需要+1
            if (this.size == 0) {
                this.startRow = 0;
                this.endRow = 0;
            } else {
                this.startRow = page.getStartRow() + 1;
                //計算實際的endRow(最後一頁的時候特殊)
                this.endRow = this.startRow - 1 + this.size;
            }
        } else if (list instanceof Collection) {
            this.pageNum = 1;
            this.pageSize = list.size();

            this.pages = this.pageSize > 0 ? 1 : 0;
            this.list = list;
            this.size = list.size();
            this.total = list.size();
            this.startRow = 0;
            this.endRow = list.size() > 0 ? list.size() - 1 : 0;
        }
        if (list instanceof Collection) {
            this.navigatePages = navigatePages;
            //計算導航頁
            calcNavigatepageNums();
            //計算前後頁,第一頁,最後一頁
            calcPage();
            //判斷頁面邊界
            judgePageBoudary();
        }
    }


.......
}

這裡只列出所有屬性和構造方法,那麼可以清晰的看到一些屬性的含義,一些屬性是如何初始化,並且初始化值是怎樣的,更多詳細情況可以自己去檢視原始碼,都有中文註釋

那麼可以很方便在頁面進行值的獲取輸出

4.在頁面獲取值(實現分頁)

<!--通過bootstrap的柵格系統佈局-->
<div class="container">

    <!--標題-->
    <div class="row">
        <div class="col-md-12">
            <h1>SSM-CRUD</h1>
        </div>

    </div>

    <!--按鈕-->
    <div class="row">
        <div class="col-md-4 col-md-offset-8">
            <button class="btn btn-primary">新增</button>
            <button class="btn btn-danger">刪除</button>
        </div>
    </div>

    <!--顯示錶格資料-->
    <div class="row">
        <div class="col-md-12">
            <table class="table table-hover">
                <tr>
                    <th>#</th>
                    <th>empName</th>
                    <th>gender</th>
                    <th>email</th>
                    <th>deptName</th>
                    <th>操作</th>
                </tr>


                <c:forEach items="${pageInfo.list}" var="emp">
                    <tr>
                        <th>${emp.empId}</th>
                        <th>${emp.empName}</th>
                        <th>${emp.gender=="M"?"男":"女" }</th>
                        <th>${emp.email}</th>
                        <th>${emp.department.deptName}</th>
                        <th>
                            <button class="btn btn-primary">
                                <span class="glyphicon glyphicon-pencil" aria-hidden="true"></span>
                                編輯
                            </button>

                            <button class="btn btn-danger">
                                <span class="glyphicon glyphicon-trash" aria-hidden="true"></span>
                                刪除
                            </button>

                        </th>
                    </tr>
                </c:forEach>

            </table>
        </div>

    </div>

    <!--顯示分頁資訊-->
    <div class="row">
        <!--文字資訊-->
        <div class="col-md-6">
            當前第 ${pageInfo.pageNum} 頁.總共 ${pageInfo.pages} 頁.一共 ${pageInfo.total} 條記錄
        </div>

        <!--點選分頁-->
        <div class="col-md-6">
            <nav aria-label="Page navigation">
                <ul class="pagination">
                    
                    <li><a href="${pageContext.request.contextPath}/emps?pn=1">首頁</a></li>
                    
                    <!--上一頁-->
                    <li>
                        <c:if test="${pageInfo.hasPreviousPage}">
                            <a href="${pageContext.request.contextPath}/emps?pn=${pageInfo.pageNum-1}" aria-label="Previous">
                                <span aria-hidden="true">«</span>
                            </a>
                        </c:if>
                    </li>

                    <!--迴圈遍歷連續顯示的頁面,若是當前頁就高亮顯示,並且沒有連結-->
                    <c:forEach items="${pageInfo.navigatepageNums}" var="page_num">
                        <c:if test="${page_num == pageInfo.pageNum}">
                            <li class="active"><a href="#">${page_num}</a></li>
                        </c:if>
                        <c:if test="${page_num != pageInfo.pageNum}">
                            <li><a href="${pageContext.request.contextPath}/emps?pn=${page_num}">${page_num}</a></li>
                        </c:if>
                    </c:forEach>

                    <!--下一頁-->
                    <li>
                        <c:if test="${pageInfo.hasNextPage}">
                            <a href="${pageContext.request.contextPath}/emps?pn=${pageInfo.pageNum+1}"
                               aria-label="Next">
                                <span aria-hidden="true">»</span>
                            </a>
                        </c:if>
                    </li>
                    
                    <li><a href="${pageContext.request.contextPath}/emps?pn=${pageInfo.pages}">尾頁</a></li>
                </ul>
            </nav>
        </div>

    </div>


</div>

最後顯示:



以上很常見的分頁需求,可以非常方便的使用。
並且支援各種資料庫,可以有多種方式進行引入外掛,對於springBoot也有非常好的整合使用。

PageHelpe開源地址


github專案地址:https://github.com/pagehelper/Mybatis-PageHelper
碼雲 專案地址:http://git.oschina.net/free/Mybatis_PageHelper