您的位置:首页 > 其它

Mybatis的插件 PageHelper 分页查询使用方法

2018-03-15 17:30 1086 查看
原文链接:http://blog.csdn.net/maoyuanming0806/article/details/77720754

Mybatis的一个插件,PageHelper,非常方便mybatis分页查询。国内牛人的一个开源项目,有兴趣的可以去看源码,都有中文注释(ps:某些源码一大堆英文,痛哭流涕!)在github上仓库地址为:Mybatis-PageHelper它支持基本主流与常用的数据库,这可以在它的文档上看到。这里记录一下使用的基本方法

0.查看文档与使用准备

开发文档有中文文档也有英文文档
PageHelper官方文档
============================================




====================================================================================








1.配置拦截器插件

这个是配置在mybatis-config.xml文件中文档中的示例:[java] view plain copy<!--   
    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>  
我的配置:
[java] view plain copy<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.在代码中使用

官方文档也有这部分说明和案例,那么我就以自己的使用案例[java] view plain copy@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对象,也可以是定连续显示的页数,这也是常用功能。注意:第七行和第九行是需要紧挨着的,中间不要夹杂其它无关语句第七行是设置页数和每页显示几条,插件会自动对接下来的sql语句加上分页方式。PageInfo中是分页的一些信息,包括总页数,当前页,总数据等。
之后把信息放在ModelAndView中就可以在前台访问了。
下面说一下为什么要把查询结果包装成PageInfo对象

3.PageInfo类说明

类源码(更多源码去github上查看即可):[java] view plain copypublic 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.在页面获取值(实现分页)

[html] view plain copy<!--通过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>  

最后显示:


以上很常见的分页需求,可以非常方便的使用。
目前Pagehelper插件支持Oracle,Mysql,MariaDB,SQLite,Hsqldb,PostgreSQL六种数据库分页,不同数据库只需要修改helperDialect就行

PageHelpe开源地址

github项目地址:https://github.com/pagehelper/Mybatis-PageHelper
码云 项目地址:http://git.oschina.net/free/Mybatis_PageHelper
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  mybatis分页插件