博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
数据量你造吗-JAVA分页
阅读量:6373 次
发布时间:2019-06-23

本文共 12116 字,大约阅读时间需要 40 分钟。

原创地址:     (泥沙砖瓦浆木匠),需要转载的,保留下! Thanks  

    学习的心态第一,解行要相应。其实《弟子规》在“余力学文”当中,一开头就强调了这一个重点。“不力行,但学文,长浮华,成何人”,这个没有侥幸的,只要学了不去做,无形当中就会增长傲慢,自己不知道。-<弟子规>

Written In The Font

    JAVA-Web 基础那块,我自己也准备.搞哪里,优化哪里然后带给大家终结.谢谢

    分页虽易,好却难.数据量,怎么办?

Content

    分页(Paging),就像个切面.能把这个切面好好的放进去也是种nice方式.

 

第一种:小数据量分页实现 (可广泛用于 门户型 网页快速开发等)


    这种比较简单,这边我们模拟实现.

    字段结构:

                   private int pageSize; //每页有多少条

                   private int rowCount; //总行数  

                   private int pageCount;//总页数

                   private int currentPage; //当前页码

   

    流程结构:               

                

    
核心:
            list.subList(index, (currentPage < pageCount) ? (index + pageSize) : rowCount);将小数据量集合,根据分页参数返回指定的list部分.这样,如果数据小的话,这样很方便的实现了分页功能.下面是JDK api里面对方法的解释:

subList(int fromIndex, int toIndex)

          返回列表中指定的 fromIndex(包括 )和 toIndex(不包括)之间的部分视图。

 

分页工具类:

package jeffli_10;import java.util.ArrayList;import java.util.List;/** 分页类:根据总记录数和分页大小对 {
@link List} 进行分页处理 */public class Pagination{ public static final int DEFAULT_PAGE_SIZE = 10; private int rowCount; private int currentPage; private int pageSize; private int pageCount; private List
list; public Pagination(List
list) { this(list, DEFAULT_PAGE_SIZE); } public Pagination(List
list, int pageSize) { this.currentPage = 1; this.list = list; this.rowCount = list.size(); setPageSize(pageSize); } private void adjustPageCount() { pageCount = (rowCount + pageSize - 1) / pageSize; } /** 获取要分页的 {
@link List} */ public List
getList() { return list; } /** 获取的 {
@link List} 当前页内容 */ public List
getCurrentList() { List
currentList = null; if(currentPage >= 1 && currentPage <= pageCount) { int index = (currentPage - 1) * pageSize; currentList = list.subList(index, (currentPage < pageCount) ? (index + pageSize) : rowCount); } return currentList; } /** 获取当前页号(从 1 开始) */ public int getCurrentPage() { return currentPage; } /** 设置当前页号(从 1 开始) */ public boolean setCurrentPage(int page) { if(page >= 1 && page <= pageCount) { currentPage = page; return true; } return false; } /** 转到下一页 */ public boolean nextPage() { return setCurrentPage(currentPage + 1); } /** 转到上一页 */ public boolean prePage() { return setCurrentPage(currentPage - 1); } /** 获取分页大小 */ public int getPageSize() { return pageSize; } /** 设置分页大小 */ public void setPageSize(int size) { if(size <= 0) size = DEFAULT_PAGE_SIZE; int index = (currentPage - 1) * pageSize; pageSize = size; if(index > pageSize) currentPage = (index + pageSize - 1) / pageSize; else currentPage = 1; adjustPageCount(); } /** 获取总页数 */ public int getPageCount() { return pageCount; } public static void main(String[] args) { final int PAGE_SIZE = 10; final int LIST_SIZE = 39; List
list = new ArrayList
(); for(int i = 1; i <= LIST_SIZE; i++) list.add(i); Pagination pg = new Pagination(list, PAGE_SIZE); for(int i = 1; i <= pg.getPageCount(); i++) { pg.setCurrentPage(i); System.out.println(pg.getCurrentList()); } } }

 

RUN,你会看到 OUTPUTS:

[1, 2, 3, 4, 5, 6, 7, 8, 9, 10][11, 12, 13, 14, 15, 16, 17, 18, 19, 20][21, 22, 23, 24, 25, 26, 27, 28, 29, 30][31, 32, 33, 34, 35, 36, 37, 38, 39]

 

第二种:大数据量,采取DAO层分页操作(普遍性需求)


环境:

        spring MVC (spring-4.0.0.RELEASE.jar)

        hibernate     (hibernate-core-4.3.5.Final.jar)

        Mysql           

 

两个核心工具类-分页

分页对象,包含所需要的所有参数及逻辑.

package sedion.jeffli.wmuitp.util;import java.util.List;import org.apache.commons.lang3.StringUtils;import com.google.common.collect.Lists;public class Page
{ //public variables public static final String ASC = "asc"; public static final String DESC = "desc"; //parameters of page protected int pageNo = 1; protected int pageSize = -1; protected String orderBy = null; protected String order = null; protected boolean autoCount = true; //results protected long totalCount = -1; protected List
result = Lists.newArrayList(); public Page() { } public Page(int pageSize) { this.pageSize = pageSize; } /** * 获得当前页的页号,序号从1开始,默认为1. */ public int getPageNo() { return pageNo; } /** * 设置当前页的页号,序号从1开始,低于1时自动调整为1. */ public void setPageNo(final int pageNo) { this.pageNo = pageNo; if (pageNo < 1) this.pageNo = 1; } /** * 返回Page对象自身的setPageNo函数,可用于连续设置。 */ public Page
pageNo(final int thePageNo) { setPageNo(thePageNo); return this; } /** * 获得每页的记录数量, 默认为-1. */ public int getPageSize() { return pageSize; } /** * 设置每页的记录数量. */ public void setPageSize(final int pageSize) { this.pageSize = pageSize; } /** * 返回Page对象自身的setPageSize函数,可用于连续设置。 */ public Page
pageSize(final int thePageSize) { setPageSize(thePageSize); return this; } /** * 根据pageNo和pageSize计算当前页第一条记录在总结果集中的位置,序号从1开始. */ public int getFirst() { return ((pageNo - 1) * pageSize) + 1; } /** * 获得排序字段,无默认值. 多个排序字段时用','分隔. */ public String getOrderBy() { return orderBy; } /** * 设置排序字段,多个排序字段时用','分隔. */ public void setOrderBy(final String orderBy) { this.orderBy = orderBy; } /** * 返回Page对象自身的setOrderBy函数,可用于连续设置。 */ public Page
orderBy(final String theOrderBy) { setOrderBy(theOrderBy); return this; } /** * 获得排序方向, 无默认值. */ public String getOrder() { return order; } /** * 设置排序方式向. * * @param order * 可选值为desc或asc,多个排序字段时用','分隔. */ public void setOrder(final String order) { String lowcaseOrder = StringUtils.lowerCase(order); String[] orders = StringUtils.split(lowcaseOrder, ','); for (String orderStr : orders) { if (!StringUtils.equals(DESC, orderStr) && !StringUtils.equals(ASC, orderStr)) {
// 检查order字符串的合法值 throw new IllegalArgumentException("排序方向" + orderStr + "不是合法值"); } } this.order = lowcaseOrder; } /** * 返回Page对象自身的setOrder函数,可用于连续设置。 */ public Page
order(final String theOrder) { setOrder(theOrder); return this; } /** * 是否已设置排序字段,无默认值. */ public boolean isOrderBySetted() { return (StringUtils.isNotBlank(orderBy) && StringUtils.isNotBlank(order)); } /** * 获得查询对象时是否先自动执行count查询获取总记录数, 默认为false. */ public boolean isAutoCount() { return autoCount; } /** * 设置查询对象时是否自动先执行count查询获取总记录数. */ public void setAutoCount(final boolean autoCount) { this.autoCount = autoCount; } /** * 返回Page对象自身的setAutoCount函数,可用于连续设置。 */ public Page
autoCount(final boolean theAutoCount) { setAutoCount(theAutoCount); return this; } // -- 访问查询结果函数 --// /** * 获得页内的记录列表. */ public List
getResult() { return result; } /** * 设置页内的记录列表. */ public void setResult(final List
result) { this.result = result; } /** * 获得总记录数, 默认值为-1. */ public long getTotalCount() { return totalCount; } /** * 设置总记录数. */ public void setTotalCount(final long totalCount) { this.totalCount = totalCount; } /** * 根据pageSize与totalCount计算总页数, 默认值为-1. */ public long getTotalPages() { if (totalCount < 0) return 1; long count = totalCount / pageSize; if (totalCount % pageSize > 0) count++; return count; } /** * 是否还有下一页. */ public boolean isHasNext() { return (pageNo + 1 <= getTotalPages()); } /** * 取得下页的页号, 序号从1开始. 当前页为尾页时仍返回尾页序号. */ public int getNextPage() { if (isHasNext()) return pageNo + 1; else return pageNo; } /** * 是否还有上一页. */ public boolean isHasPre() { return (pageNo - 1 >= 1); } /** * 取得上页的页号, 序号从1开始. 当前页为首页时返回首页序号. */ public int getPrePage() { if (isHasPre()) return pageNo - 1; else return pageNo; } public long getBegin() { return Math.max(1, getPageNo() - pageSize / 2); } public long getEnd() { return getTotalPages(); }}

 

分页初始化(包括参数变化)

package sedion.jeffli.wmuitp.util;import javax.servlet.http.HttpServletRequest;import org.apache.commons.lang3.StringUtils;import com.sun.org.apache.xml.internal.resolver.helpers.PublicId;import sedion.jeffli.wmuitp.entity.SubjectInfor;/** * 分页工具 *  */public class PageUtil {    public static int PAGE_SIZE             = 20;    public static int MAX_SIZE              = 9999;        public static final String PAGE_NUM_STR = "pageNum";        /**     * 初始化分页     * @param page        page对象     * @param request     请求体     * @return     */    public static int[] init(Page
page, HttpServletRequest request) { int pageNum = Integer.parseInt(StringUtils.defaultIfBlank(request.getParameter(PAGE_NUM_STR), "1")); page.setPageNo(Integer.valueOf(pageNum)); page.setPageSize(page.getPageSize()); int firstResult = page.getFirst() - 1; int maxResults = page.getPageSize(); return new int[] { firstResult, maxResults }; }}

#这里我们用request.getParameter(PAGE_NUM_STR) 获取分页操作时改变的字段.这样不必要每次都在Controller上附带参数了.

 

页面端:

显示
条,共${page.getTotalCount()}条

 

然后到Controller层:

@RequestMapping(value = "/subjectInfors")    public ModelAndView subjectInfos()    {            ModelAndView mav = new ModelAndView(SubjectInforWebConstant.getSubjectInforListView());                try {                        Page
page = new Page<>(PageUtil.PAGE_SIZE); int[] pageParams = PageUtil.init(page,request);//分页初始化 subjectInforService.getSubjectInforsPages(page, pageParams); mav.addObject(MainWebConstant.getPage(), page); } catch (Exception e) { e.printStackTrace(); } return mav; }

 

调用Service层:

@Override    public List
getSubjectInforsPages(Page
page, int[] pageParams) { List
results = new ArrayList<>(); StringBuffer resultsHQL = new StringBuffer(All_SUBJECT_INFORS); try { results = subjectInforDAO.findByPage(resultsHQL.toString(), pageParams[0], pageParams[1]); page.setTotalCount(subjectInforDAO.getCount(resultsHQL.toString())); page.setResult(results); } catch (Exception e) { e.printStackTrace(); } return results; }

 

调用DAO层:

/**     * find entity-s of database by hql     * --------------------------------------------------------     * @param(String)     hql                 * @param(String)     offset        当前标识         * @param(String)     pageSize    分页大小     * @return            null/List
*/ @SuppressWarnings("unchecked") public List
findByPage(String hql, int offset, int pageSize) { if (hql == null) { return new ArrayList
(); } Query query = createQuery(hql); if (!(offset == 0 && pageSize == 0)) { query.setFirstResult(offset).setMaxResults(pageSize); } if (query.list() != null) return query.list(); else return null; }

 

实现的效果图:

#这样分页就简简单单实现了.

 

Editor's Note

             找我加群,一起共勉!

你可能感兴趣的文章
Android 插件框架机制之预热篇
查看>>
01奇数矩阵代码
查看>>
Java命令行监控工具(jmap,jstack,jstat,jinfo,jps)
查看>>
0915 - 宁愿写代码,不愿写文案
查看>>
Promise中多个回调函数之间的数据传递
查看>>
前端和后端的发展路径
查看>>
10个你在JavaScript面试前需要掌握的概念
查看>>
浅识JAVA设计模式——观察者模式
查看>>
React事件机制 - 源码概览(上)
查看>>
Go 语言标准库 text/template 包深入浅出
查看>>
[译]Rollup - 下一代 ES6 模块化打包工具 - 对 Rich Harris 的采访
查看>>
Node 框架接入 ELK 实践总结
查看>>
董朝:打造云存储服务——移动端数据存储与分发
查看>>
物联网操作系统安全性分析
查看>>
Android :这是一份详细 & 全面的 SQLlite数据库 使用手册
查看>>
从零实现Vue的组件库(七)- Message-Box 实现
查看>>
模式系统与最简单的Node.js MVC Web Server设计
查看>>
数据库:SwiftSQlite
查看>>
深入浅出node读书笔记
查看>>
如何看待 Google 最新的系统 Fuchsia?
查看>>