备案 控制台
开发者社区 开发与运维 文章 正文

数据量你造吗-JAVA分页

简介:

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

Written In The Font

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

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

Content

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

 

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


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

    字段结构:

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

                   private int rowCount; //总行数  

                   private int pageCount;//总页数

                   private int currentPage; //当前页码

   

    流程结构:               

                 YTAY2KI}9BXPN(~3EA9BI6D

     核心:
            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<Integer> list = new ArrayList<Integer>();
        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<T> {

    //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<T> 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<T> 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<T> 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<T> 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<T> 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<T> autoCount(final boolean theAutoCount) 
    {
        setAutoCount(theAutoCount);
        return this;
    }

    // -- 访问查询结果函数 --//

    /**
     * 获得页内的记录列表.
     */
    public List<T> getResult() 
    {
        return result;
    }

    /**
     * 设置页内的记录列表.
     */
    public void setResult(final List<T> 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上附带参数了.

 

页面端:

<form id="pagerForm" method="post" action="${ctx}/subjectInfor/subjectInfors">
        <input type="hidden" name="pageNum"     value=${page.getPageNo()} />
        <input type="hidden" name="numPerPage"     value=${page.getPageSize()} />
    </form>
    <div class="panelBar">
        <div class="pages">
            <span>显示</span>
            <select class="combox" name="numPerPage" onchange="navTabPageBreak({numPerPage:this.value})">
                <option value="20"     <#if numPerPage == 20>    selected</#if>>20    </option>
                <option value="50"     <#if numPerPage == 50>    selected</#if>>50    </option>
                <option value="100" <#if numPerPage == 100>    selected</#if>>100    </option>
                <option value="200" <#if numPerPage == 200>    selected</#if>>200    </option>
            </select>
            <span>条,共${page.getTotalCount()}条</span>
        </div>
    <div class="pagination" totalCount=${page.getTotalCount()} numPerPage=${page.getPageSize()} pageNumShown="10" currentPage=${page.getPageNo()}></div>

 

然后到Controller层:

@RequestMapping(value = "/subjectInfors")
    public ModelAndView subjectInfos()
    {    
        ModelAndView mav = new ModelAndView(SubjectInforWebConstant.getSubjectInforListView());
        
        try {
            
            Page<SubjectInfor> 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<SubjectInfor> getSubjectInforsPages(Page<SubjectInfor> page, int[] pageParams)
    {
        List<SubjectInfor> 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<T>
     */
    @SuppressWarnings("unchecked")
    public List<T> findByPage(String hql, int offset, int pageSize) 
    {
        if (hql == null) 
        {
            return new ArrayList<T>();
        }
        Query query = createQuery(hql);
        if (!(offset == 0 && pageSize == 0)) 
        {
            query.setFirstResult(offset).setMaxResults(pageSize);
        }
        if (query.list() != null)
            return query.list();
        else
            return null;

    }

实现的效果图:

image

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

 

二哥聊RPA
目录
相关文章
穆雄雄.
|
1月前
|
Web App开发 SQL Java
javaweb实现分页(二)
javaweb实现分页(二)
穆雄雄.
24 1
穆雄雄.
|
1月前
|
Web App开发 Java 关系型数据库
java中部的分页实现(二)
java中部的分页实现(二)
穆雄雄.
23 1
穆雄雄.
|
1月前
|
SQL 关系型数据库 MySQL
javaweb中实现分页,持续更新……
javaweb中实现分页,持续更新……
穆雄雄.
34 1
穆雄雄.
|
1月前
Mybatis+mysql动态分页查询数据案例——分页工具类(Page.java)
Mybatis+mysql动态分页查询数据案例——分页工具类(Page.java)
穆雄雄.
37 1
Alone秋
|
7月前
|
SQL 前端开发 Java
java通用分页前端(2)
java通用分页前端(2)
Alone秋
44 0
Ar.小白
|
8月前
|
前端开发 Java 测试技术
java通用分页(后端)
1.通用分页是什么? Java通用分页是指在Java编程语言中实现的一种通用分页功能。它通常用于在Java Web应用中展示大量数据或查询结果,并将其分页显示给用户。
Ar.小白
128 1
北京宏哥
|
19天前
|
Java 测试技术 Python
《手把手教你》系列技巧篇(五十八)-java+ selenium自动化测试-分页测试(详细教程)
【5月更文挑战第22天】本文介绍了自动化测试分页的实现方法。首先,文章提出了测试分页时关注的三个关键点:总页数、当前页数和页码导航的可用性。接着,作者分享了一个实用网站([https://www.jq22.com/](https://www.jq22.com/))以找到示例进行实践。在代码部分,展示了使用Java和Selenium进行自动化测试的示例代码,包括获取总页数、遍历所有页面及判断当前页面等操作。最后,简要总结了分页自动化测试的实现过程。
北京宏哥
24 1
渐暖
|
1月前
|
SQL 存储 前端开发
【java】树形结构分页(真分页)
【java】树形结构分页(真分页)
渐暖
50 1
夏之以寒
|
1月前
|
XML 监控 druid
【Java专题_02】springboot+mybatis+pagehelper分页插件+druid数据源详细教程
【Java专题_02】springboot+mybatis+pagehelper分页插件+druid数据源详细教程
夏之以寒
74 0
前端歌谣
|
10月前
java202304java学习笔记第六十六天-ssm-动态sql-plugins分页数据关联实现
java202304java学习笔记第六十六天-ssm-动态sql-plugins分页数据关联实现
前端歌谣
28 0

热门文章

最新文章

  • 1
    代码块:在Java中用{}括起来的代码
  • 2
    【Java入门提高篇】Day8 Java内部类——匿名内部类
  • 3
    java进阶-常用数据结构以及算法思想
  • 4
    排查Java高CPU占用原因
  • 5
    java 小数点取2位并且四舍五入
  • 6
    第三章 AOP 通过Java API创建增强
  • 7
    在Eclipse中将Java项目打包为jar
  • 8
    后浪拍前浪-覆写父类方法 | 带你学《Java面向对象编程》之三十九
  • 9
    Java设计模式之代理模式
  • 10
    Java NIO -- 通道 Channel
  • 1
    Java并发编程:理解并应用ReentrantLock
    24
  • 2
    Java并发编程:深入理解线程池
    12
  • 3
    Java 8新特性解析及应用区块链技术在供应链管理中的应用与挑战
    25
  • 4
    Java 效率编码 必备插件 Lombok 让代码更优雅
    12
  • 5
    Java代码一键生成数据库文档(案例详解)
    37
  • 6
    java一行代码实现RESTFul接口
    25
  • 7
    Java远程连接本地开源分布式搜索引擎ElasticSearch
    20
  • 8
    Spring Boot单元测试报错java.lang.IllegalStateException: Could not load TestContextBootstrapper [null]
    30
  • 9
    Java并发编程:深入理解线程池
    23
  • 10
    Java中 a+=b和a=a+b有什么区别?
    14
  • 相关课程

    更多
  • Java面试疑难点解析 - 面试技巧及语言基础
  • Java面试疑难点解析 - Java Web开发
  • Java面试疑难点解析 - 系统架构及项目设计
  • Java编程入门
  • Java面向对象编程
  • Java高级编程
  • 相关电子书

    更多
  • Spring Cloud Alibaba - 重新定义 Java Cloud-Native
  • The Reactive Cloud Native Arch
  • JAVA开发手册1.5.0
  • 相关实验场景

    更多
  • 阿里云平台上进行Java程序的编译与运行
  • 使用Java面向对象编写网络通信程序应用
  • Elasticsearch Java API Client 开发
  • 手动部署Java Web环境(Alibaba Cloud Linux 2)
  • 搭建Java Web开发环境(Anolis OS)
  • RocketMQ中使用Java客户端发送消息和消费的应用
  • 下一篇
    2024年阿里云免费云服务器及学生云服务器申请教程参考

    深圳SEO优化公司甘孜网络广告推广连云港网站搭建公司德阳关键词排名包年推广公司滁州网站设计模板咸阳网站优化排名哪家好北海网站改版报价保定网络营销多少钱河源网络营销多少钱乌海企业网站制作哪家好宿迁关键词按天计费多少钱定西设计网站报价济源网站制作设计公司益阳关键词按天计费报价宁波阿里店铺托管南阳网站建设设计价格双龙SEO按效果付费哪家好山南网站排名优化价格苏州网站推广哪家好南平网站推广方案乐山seo优化哪家好昌吉网站设计公司巴中关键词排名公司定西SEO按效果付费报价泰安网站开发报价垦利至尊标王哪家好成都百姓网标王推广推荐广元网站搜索优化价格哈尔滨建站推荐桂林模板网站建设价格平凉seo网站优化多少钱歼20紧急升空逼退外机英媒称团队夜以继日筹划王妃复出草木蔓发 春山在望成都发生巨响 当地回应60岁老人炒菠菜未焯水致肾病恶化男子涉嫌走私被判11年却一天牢没坐劳斯莱斯右转逼停直行车网传落水者说“没让你救”系谣言广东通报13岁男孩性侵女童不予立案贵州小伙回应在美国卖三蹦子火了淀粉肠小王子日销售额涨超10倍有个姐真把千机伞做出来了近3万元金手镯仅含足金十克呼北高速交通事故已致14人死亡杨洋拄拐现身医院国产伟哥去年销售近13亿男子给前妻转账 现任妻子起诉要回新基金只募集到26元还是员工自购男孩疑遭霸凌 家长讨说法被踢出群充个话费竟沦为间接洗钱工具新的一天从800个哈欠开始单亲妈妈陷入热恋 14岁儿子报警#春分立蛋大挑战#中国投资客涌入日本东京买房两大学生合买彩票中奖一人不认账新加坡主帅:唯一目标击败中国队月嫂回应掌掴婴儿是在赶虫子19岁小伙救下5人后溺亡 多方发声清明节放假3天调休1天张家界的山上“长”满了韩国人?开封王婆为何火了主播靠辱骂母亲走红被批捕封号代拍被何赛飞拿着魔杖追着打阿根廷将发行1万与2万面值的纸币库克现身上海为江西彩礼“减负”的“试婚人”因自嘲式简历走红的教授更新简介殡仪馆花卉高于市场价3倍还重复用网友称在豆瓣酱里吃出老鼠头315晚会后胖东来又人满为患了网友建议重庆地铁不准乘客携带菜筐特朗普谈“凯特王妃P图照”罗斯否认插足凯特王妃婚姻青海通报栏杆断裂小学生跌落住进ICU恒大被罚41.75亿到底怎么缴湖南一县政协主席疑涉刑案被控制茶百道就改标签日期致歉王树国3次鞠躬告别西交大师生张立群任西安交通大学校长杨倩无缘巴黎奥运

    深圳SEO优化公司 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化