说明:

(1) 为什么写本篇博客?:

● 在【SpringBoot电商项目商品分类模块后台的分类列表平铺接口】中,实现分页功能时,使用到了PageHelper分页插件;

● 但是,在【SpringBoot电商项目商品分类模块后台的分类列表平铺接口】中,我们使用的是PageHelper中的PageInfo对象;

● 而,在【MyBatis进阶五:PageHelper分页插件;】中,我们第一次遇到PageHelper时候,使用的是PageHelper中的Page对象;

● 所以,本篇博客,就分析一下:PageHelper分页插件中的:Page和PageInfo的区别;

(2) 本篇博客参考的博客有:

●【Page和PageInfo】,该文的作者是【程序员^晓洋】;


一:Page和PageInfo;(这儿,归纳了两个对象的属性,总结的不错;)

这儿的内容,完全照抄自【Page和PageInfo】,该文的作者是【程序员^晓洋】;

1. Page和PageInfo简介;

两者都能获取到数据,

Page是一个ArrayListList。

PageInfo是一个对象,能获取到的数据比Page多;

2.Page和PageInfo,具体属性分析;

Page对象:

 
     private int pageNum;      //当前页码
     private int pageSize;     //每页数据的数量
     private int startRow;     //始页首行行号
     private int endRow;               //尾页尾行行号
     private long total;               //总记录数
     private int pages;                //总页数
     private Boolean reasonable; //分页合理化
     private Boolean pageSizeZero;
 //当设置为true的时候,如果pagesize设置为0(或RowBounds的limit=0),就不执行分页,返回全部结果

PageInfo对象:

         private int pageNum;                          //当前页
         private int pageSize;                 //每页显示数据条数
         private int size;                             //当前页的数量
         private int startRow;                         //始页首行行号
         private int endRow;                           //尾页尾行行号
         private long total;                           //总记录数
         private int pages;                            //总页数
         private List<T list;                 //查询结果的数据
         private int firstPage;                        //首页
         private int prePage;                  //上一页
         private int nextPage;                 // 下一页
         private int lastPage;                 //最后一页
         private boolean isFirstPage;  //是不是第一页
         private boolean isLastPage;           //是不是最后一页
         private boolean hasPreviousPage;//有没有上一页
         private boolean hasNextPage;  //有没有下一页
         private int navigatePages;            //所有导航页号
         private int[] navigatepageNums;       //导航页码数
 

二:Page和PageInfo:源码;(这部分,仅供参考,爱看不看)

1.Page源码;

/*
 * The MIT License (MIT)
 *
 * Copyright (c) 2014-2017 [email protected]
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
 
package com.github.pagehelper;
 
import java.io.Closeable;
import java.util.ArrayList;
import java.util.List;
 
/**
 * Mybatis - 分页对象
 *
 * @author liuzh/abel533/isea533
 * @version 3.6.0
 *          项目地址 : http://git.oschina.net/free/Mybatis_PageHelper
 */
public class Page<E> extends ArrayList<E> implements Closeable {
    private static final long serialVersionUID = 1L;
 
    /**
     * 页码,从1开始
     */
    private int pageNum;
    /**
     * 页面大小
     */
    private int pageSize;
    /**
     * 起始行
     */
    private int startRow;
    /**
     * 末行
     */
    private int endRow;
    /**
     * 总数
     */
    private long total;
    /**
     * 总页数
     */
    private int pages;
    /**
     * 包含count查询
     */
    private boolean count = true;
    /**
     * 分页合理化
     */
    private Boolean reasonable;
    /**
     * 当设置为true的时候,如果pagesize设置为0(或RowBounds的limit=0),就不执行分页,返回全部结果
     */
    private Boolean pageSizeZero;
    /**
     * 进行count查询的列名
     */
    private String countColumn;
    /**
     * 排序
     */
    private String orderBy;
    /**
     * 只增加排序
     */
    private boolean orderByOnly;
 
    public Page() {
        super();
    }
 
    public Page(int pageNum, int pageSize) {
        this(pageNum, pageSize, true, null);
    }
 
    public Page(int pageNum, int pageSize, boolean count) {
        this(pageNum, pageSize, count, null);
    }
 
    private Page(int pageNum, int pageSize, boolean count, Boolean reasonable) {
        super(0);
        if (pageNum == 1 && pageSize == Integer.MAX_VALUE) {
            pageSizeZero = true;
            pageSize = 0;
        }
        this.pageNum = pageNum;
        this.pageSize = pageSize;
        this.count = count;
        calculateStartAndEndRow();
        setReasonable(reasonable);
    }
 
    /**
     * int[] rowBounds
     * 0 : offset
     * 1 : limit
     */
    public Page(int[] rowBounds, boolean count) {
        super(0);
        if (rowBounds[0] == 0 && rowBounds[1] == Integer.MAX_VALUE) {
            pageSizeZero = true;
            this.pageSize = 0;
        } else {
            this.pageSize = rowBounds[1];
            this.pageNum = rowBounds[1] != 0 ? (int) (Math.ceil(((double) rowBounds[0] + rowBounds[1]) / rowBounds[1])) : 0;
        }
        this.startRow = rowBounds[0];
        this.count = count;
        this.endRow = this.startRow + rowBounds[1];
    }
 
    public List<E> getResult() {
        return this;
    }
 
    public int getPages() {
        return pages;
    }
 
    public Page<E> setPages(int pages) {
        this.pages = pages;
        return this;
    }
 
    public int getEndRow() {
        return endRow;
    }
 
    public Page<E> setEndRow(int endRow) {
        this.endRow = endRow;
        return this;
    }
 
    public int getPageNum() {
        return pageNum;
    }
 
    public Page<E> setPageNum(int pageNum) {
        //分页合理化,针对不合理的页码自动处理
        this.pageNum = ((reasonable != null && reasonable) && pageNum <= 0) ? 1 : pageNum;
        return this;
    }
 
    public int getPageSize() {
        return pageSize;
    }
 
    public Page<E> setPageSize(int pageSize) {
        this.pageSize = pageSize;
        return this;
    }
 
    public int getStartRow() {
        return startRow;
    }
 
    public Page<E> setStartRow(int startRow) {
        this.startRow = startRow;
        return this;
    }
 
    public long getTotal() {
        return total;
    }
 
    public void setTotal(long total) {
        this.total = total;
        if (total == -1) {
            pages = 1;
            return;
        }
        if (pageSize > 0) {
            pages = (int) (total / pageSize + ((total % pageSize == 0) ? 0 : 1));
        } else {
            pages = 0;
        }
        //分页合理化,针对不合理的页码自动处理
        if ((reasonable != null && reasonable) && pageNum > pages) {
            if(pages!=0){
                pageNum = pages;
            }
            calculateStartAndEndRow();
        }
    }
 
    public Boolean getReasonable() {
        return reasonable;
    }
 
    public Page<E> setReasonable(Boolean reasonable) {
        if (reasonable == null) {
            return this;
        }
        this.reasonable = reasonable;
        //分页合理化,针对不合理的页码自动处理
        if (this.reasonable && this.pageNum <= 0) {
            this.pageNum = 1;
            calculateStartAndEndRow();
        }
        return this;
    }
 
    public Boolean getPageSizeZero() {
        return pageSizeZero;
    }
 
    public Page<E> setPageSizeZero(Boolean pageSizeZero) {
        if (pageSizeZero != null) {
            this.pageSizeZero = pageSizeZero;
        }
        return this;
    }
    public String getOrderBy() {
        return orderBy;
    }
 
    public <E> Page<E> setOrderBy(String orderBy) {
        this.orderBy = orderBy;
        return (Page<E>) this;
    }
 
    public boolean isOrderByOnly() {
        return orderByOnly;
    }
 
    public void setOrderByOnly(boolean orderByOnly) {
        this.orderByOnly = orderByOnly;
    }
 
    /**
     * 计算起止行号
     */
    private void calculateStartAndEndRow() {
        this.startRow = this.pageNum > 0 ? (this.pageNum - 1) * this.pageSize : 0;
        this.endRow = this.startRow + this.pageSize * (this.pageNum > 0 ? 1 : 0);
    }
 
    public boolean isCount() {
        return this.count;
    }
 
    public Page<E> setCount(boolean count) {
        this.count = count;
        return this;
    }
 
    /**
     * 设置页码
     *
     * @param pageNum
     * @return
     */
    public Page<E> pageNum(int pageNum) {
        //分页合理化,针对不合理的页码自动处理
        this.pageNum = ((reasonable != null && reasonable) && pageNum <= 0) ? 1 : pageNum;
        return this;
    }
 
    /**
     * 设置页面大小
     *
     * @param pageSize
     * @return
     */
    public Page<E> pageSize(int pageSize) {
        this.pageSize = pageSize;
        calculateStartAndEndRow();
        return this;
    }
 
    /**
     * 是否执行count查询
     *
     * @param count
     * @return
     */
    public Page<E> count(Boolean count) {
        this.count = count;
        return this;
    }
 
    /**
     * 设置合理化
     *
     * @param reasonable
     * @return
     */
    public Page<E> reasonable(Boolean reasonable) {
        setReasonable(reasonable);
        return this;
    }
 
    /**
     * 当设置为true的时候,如果pagesize设置为0(或RowBounds的limit=0),就不执行分页,返回全部结果
     *
     * @param pageSizeZero
     * @return
     */
    public Page<E> pageSizeZero(Boolean pageSizeZero) {
        setPageSizeZero(pageSizeZero);
        return this;
    }
 
    /**
     * 指定 count 查询列
     *
     * @param columnName
     * @return
     */
    public Page<E> countColumn(String columnName) {
        this.countColumn = columnName;
        return this;
    }
 
    public PageInfo<E> toPageInfo() {
        PageInfo<E> pageInfo = new PageInfo<E>(this);
        return pageInfo;
    }
 
    public PageSerializable<E> toPageSerializable() {
        PageSerializable<E> serializable = new PageSerializable<E>(this);
        return serializable;
    }
 
    public <E> Page<E> doSelectPage(ISelect select) {
        select.doSelect();
        return (Page<E>) this;
    }
 
    public <E> PageInfo<E> doSelectPageInfo(ISelect select) {
        select.doSelect();
        return (PageInfo<E>) this.toPageInfo();
    }
 
    public <E> PageSerializable<E> doSelectPageSerializable(ISelect select) {
        select.doSelect();
        return (PageSerializable<E>) this.toPageSerializable();
    }
 
    public long doCount(ISelect select) {
        this.pageSizeZero = true;
        this.pageSize = 0;
        select.doSelect();
        return this.total;
    }
 
    public String getCountColumn() {
        return countColumn;
    }
 
    public void setCountColumn(String countColumn) {
        this.countColumn = countColumn;
    }
 
    @Override
    public String toString() {
        return "Page{" +
                "count=" + count +
                ", pageNum=" + pageNum +
                ", pageSize=" + pageSize +
                ", startRow=" + startRow +
                ", endRow=" + endRow +
                ", total=" + total +
                ", pages=" + pages +
                ", reasonable=" + reasonable +
                ", pageSizeZero=" + pageSizeZero +
                '}' + super.toString();
    }
 
    @Override
    public void close() {
        PageHelper.clearPage();
    }
}

2.PageInfo源码;

/*
 * The MIT License (MIT)
 *
 * Copyright (c) 2014-2017 [email protected]
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
 
package com.github.pagehelper;
 
import java.util.Collection;
import java.util.List;
 
/**
 * 对Page<E>结果进行包装
 * <p/>
 * 新增分页的多项属性,主要参考:http://bbs.csdn.net/topics/360010907
 *
 * @author liuzh/abel533/isea533
 * @version 3.3.0
 * @since 3.2.2
 * 项目地址 : http://git.oschina.net/free/Mybatis_PageHelper
 */
@SuppressWarnings({"rawtypes", "unchecked"})
public class PageInfo<T> extends PageSerializable<T> {
    //当前页
    private int pageNum;
    //每页的数量
    private int pageSize;
    //当前页的数量
    private int size;
 
    //由于startRow和endRow不常用,这里说个具体的用法
    //可以在页面中"显示startRow到endRow 共size条数据"
 
    //当前页面第一个元素在数据库中的行号
    private int startRow;
    //当前页面最后一个元素在数据库中的行号
    private int endRow;
    //总页数
    private int pages;
 
    //前一页
    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) {
        super(list);
        if (list instanceof Page) {
            Page page = (Page) list;
            this.pageNum = page.getPageNum();
            this.pageSize = page.getPageSize();
 
            this.pages = page.getPages();
            this.size = page.size();
            //由于结果是>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.size = list.size();
            this.startRow = 0;
            this.endRow = list.size() > 0 ? list.size() - 1 : 0;
        }
        if (list instanceof Collection) {
            this.navigatePages = navigatePages;
            //计算导航页
            calcNavigatepageNums();
            //计算前后页,第一页,最后一页
            calcPage();
            //判断页面边界
            judgePageBoudary();
        }
    }
 
    public static <T> PageInfo<T> of(List<T> list) {
        return new PageInfo<T>(list);
    }
 
    public static <T> PageInfo<T> of(List<T> list, int navigatePages) {
        return new PageInfo<T>(list, navigatePages);
    }
 
    /**
     * 计算导航页
     */
    private void calcNavigatepageNums() {
        //当总页数小于或等于导航页码数时
        if (pages <= navigatePages) {
            navigatepageNums = new int[pages];
            for (int i = 0; i < pages; i++) {
                navigatepageNums[i] = i + 1;
            }
        } else { //当总页数大于导航页码数时
            navigatepageNums = new int[navigatePages];
            int startNum = pageNum - navigatePages / 2;
            int endNum = pageNum + navigatePages / 2;
 
            if (startNum < 1) {
                startNum = 1;
                //(最前navigatePages页
                for (int i = 0; i < navigatePages; i++) {
                    navigatepageNums[i] = startNum++;
                }
            } else if (endNum > pages) {
                endNum = pages;
                //最后navigatePages页
                for (int i = navigatePages - 1; i >= 0; i--) {
                    navigatepageNums[i] = endNum--;
                }
            } else {
                //所有中间页
                for (int i = 0; i < navigatePages; i++) {
                    navigatepageNums[i] = startNum++;
                }
            }
        }
    }
 
    /**
     * 计算前后页,第一页,最后一页
     */
    private void calcPage() {
        if (navigatepageNums != null && navigatepageNums.length > 0) {
            navigateFirstPage = navigatepageNums[0];
            navigateLastPage = navigatepageNums[navigatepageNums.length - 1];
            if (pageNum > 1) {
                prePage = pageNum - 1;
            }
            if (pageNum < pages) {
                nextPage = pageNum + 1;
            }
        }
    }
 
    /**
     * 判定页面边界
     */
    private void judgePageBoudary() {
        isFirstPage = pageNum == 1;
        isLastPage = pageNum == pages || pages == 0;
        hasPreviousPage = pageNum > 1;
        hasNextPage = pageNum < pages;
    }
 
    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 getSize() {
        return size;
    }
 
    public void setSize(int size) {
        this.size = size;
    }
 
    public int getStartRow() {
        return startRow;
    }
 
    public void setStartRow(int startRow) {
        this.startRow = startRow;
    }
 
    public int getEndRow() {
        return endRow;
    }
 
    public void setEndRow(int endRow) {
        this.endRow = endRow;
    }
 
    public int getPages() {
        return pages;
    }
 
    public void setPages(int pages) {
        this.pages = pages;
    }
 
    public int getPrePage() {
        return prePage;
    }
 
    public void setPrePage(int prePage) {
        this.prePage = prePage;
    }
 
    public int getNextPage() {
        return nextPage;
    }
 
    public void setNextPage(int nextPage) {
        this.nextPage = nextPage;
    }
 
    public boolean isIsFirstPage() {
        return isFirstPage;
    }
 
    public void setIsFirstPage(boolean isFirstPage) {
        this.isFirstPage = isFirstPage;
    }
 
    public boolean isIsLastPage() {
        return isLastPage;
    }
 
    public void setIsLastPage(boolean isLastPage) {
        this.isLastPage = isLastPage;
    }
 
    public boolean isHasPreviousPage() {
        return hasPreviousPage;
    }
 
    public void setHasPreviousPage(boolean hasPreviousPage) {
        this.hasPreviousPage = hasPreviousPage;
    }
 
    public boolean isHasNextPage() {
        return hasNextPage;
    }
 
    public void setHasNextPage(boolean hasNextPage) {
        this.hasNextPage = hasNextPage;
    }
 
    public int getNavigatePages() {
        return navigatePages;
    }
 
    public void setNavigatePages(int navigatePages) {
        this.navigatePages = navigatePages;
    }
 
    public int[] getNavigatepageNums() {
        return navigatepageNums;
    }
 
    public void setNavigatepageNums(int[] navigatepageNums) {
        this.navigatepageNums = navigatepageNums;
    }
 
    public int getNavigateFirstPage() {
        return navigateFirstPage;
    }
 
    public int getNavigateLastPage() {
        return navigateLastPage;
    }
 
    public void setNavigateFirstPage(int navigateFirstPage) {
        this.navigateFirstPage = navigateFirstPage;
    }
 
    public void setNavigateLastPage(int navigateLastPage) {
        this.navigateLastPage = navigateLastPage;
    }
 
    @Override
    public String toString() {
        final StringBuilder sb = new StringBuilder("PageInfo{");
        sb.append("pageNum=").append(pageNum);
        sb.append(", pageSize=").append(pageSize);
        sb.append(", size=").append(size);
        sb.append(", startRow=").append(startRow);
        sb.append(", endRow=").append(endRow);
        sb.append(", total=").append(total);
        sb.append(", pages=").append(pages);
        sb.append(", list=").append(list);
        sb.append(", prePage=").append(prePage);
        sb.append(", nextPage=").append(nextPage);
        sb.append(", isFirstPage=").append(isFirstPage);
        sb.append(", isLastPage=").append(isLastPage);
        sb.append(", hasPreviousPage=").append(hasPreviousPage);
        sb.append(", hasNextPage=").append(hasNextPage);
        sb.append(", navigatePages=").append(navigatePages);
        sb.append(", navigateFirstPage=").append(navigateFirstPage);
        sb.append(", navigateLastPage=").append(navigateLastPage);
        sb.append(", navigatepageNums=");
        if (navigatepageNums == null) {
            sb.append("null");
        } else {
            sb.append('[');
            for (int i = 0; i < navigatepageNums.length; ++i) {
                sb.append(i == 0 ? "" : ", ").append(navigatepageNums[i]);
            }
            sb.append(']');
        }
        sb.append('}');
        return sb.toString();
    }
}

三:Page和PageInfo:使用;(重要!)

(1)首先,就是开启分页,设置【pageNum:当前页】和【pageSize:每页记录数】;

(2)然后,我们会利用Mybatis,根据上面设置的分页条件,去查询数据库,得到查询结果;

(3)然后,可以根据前端对分页数据格式的要求,可以把(3)中查到的分页数据,包装成Page对象;

(4)或者,包装成PageInfo对象;

(5)使用Page对象还是使用PageInfo对象?

● 目前的个人理解:使用Page对象还是PageInfo对象,需要根据前端的要求,或者说是根据接口对返回数据的格式的要求;

● 比如,在【[Spring Boot电商项目29:商品分类模块八:后台的【分类列表(平铺)】接口;](https://blog.csdn.net/csucsgoat/article/details/123159442】的接口文档要求,接口的返回是:

所以,对于这样的接口要求,很自然就是使用PageInfo对象;