说明:
(1)为什么写本篇博客?:
● 在【Spring Boot电商项目29:商品分类模块八:后台的【分类列表(平铺)】接口;】中,实现分页功能时,使用到了PageHelper分页插件;
● 但是,在【Spring Boot电商项目29:商品分类模块八:后台的【分类列表(平铺)】接口;】中,我们使用的是PageHelper中的PageInfo对象;
● 而,在【MyBatis进阶五:PageHelper分页插件;】中,我们第一次遇到PageHelper时候,使用的是PageHelper中的Page对象;
● 所以,本篇博客,就分析一下:PageHelper分页插件中的:Page和PageInfo的区别;
(2)本篇博客参考的博客有:
● 【Page和PageInfo】,该文的作者是【程序员^晓洋】;
目录
一:Page和PageInfo;(这儿,归纳了两个对象的属性,总结的不错;)
二:Page和PageInfo:源码;(这部分,仅供参考,爱看不看)
(1)首先,就是开启分页,设置【pageNum:当前页】和【pageSize:每页记录数】;
(2)然后,我们会利用Mybatis,根据上面设置的分页条件,去查询数据库,得到查询结果;
(3)然后,可以根据前端对分页数据格式的要求,可以把(3)中查到的分页数据,包装成Page对象;
一: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 abel533@gmail.com * * 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 abel533@gmail.com * * 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:商品分类模块八:后台的【分类列表(平铺)】接口;】中,【分类列表(平铺)接口】的接口文档要求,接口的返回是:
所以,对于这样的接口要求,很自然就是使用PageInfo对象;