文档章节

数据量你造吗-JAVA分页

泥沙砖瓦浆木匠
 泥沙砖瓦浆木匠
发布于 2014/05/31 18:03
字数 1982
阅读 414
收藏 30

数据量你造吗-JAVA分页

原创地址:   http://www.cnblogs.com/Alandre/  (泥沙砖瓦浆木匠),需要转载的,保留下! Thanks  

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

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

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

 

Editor's Note

             找我加群,一起共勉!

QQ截图20140525001523_thumb[3]


© 著作权归作者所有

共有 人打赏支持
泥沙砖瓦浆木匠

泥沙砖瓦浆木匠

粉丝 794
博文 139
码字总数 170656
作品 4
杭州
程序员
加载中

评论(5)

微微我信
微微我信
mark
泥沙砖瓦浆木匠
泥沙砖瓦浆木匠

引用来自“王爵”的评论

mark
共勉
泥沙砖瓦浆木匠
泥沙砖瓦浆木匠

引用来自“冷月孤寒”的评论

马克
共勉
咯咯鸡
咯咯鸡
马克
王爵nice
王爵nice
mark
我对 Java Web框架 的一点见解

前天看到了 Apache Click 这个项目,有点感触。 很多 Java 的Web框架都在走一条错误的路线,花大量的工作在服务器端代码的封装,搞出N多模式,但是实际的开发量并没有减少,有时候反倒而会加...

红薯
2009/02/23
0
23
MySQL多数据源笔记5-ShardingJDBC实战

Sharding-JDBC集分库分表、读写分离、分布式主键、柔性事务和数据治理与一身,提供一站式的解决分布式关系型数据库的解决方案。 从2.x版本开始,Sharding-JDBC正式将包名、Maven坐标、码云仓...

狂小白
03/19
0
0
分享几个JAVA程序员们最容易犯的错误,你中了几枪?

都说Java语言是一门简单的编程语言,基于C++演化而来,剔除了很多C++中的复杂特性,但这并不能保证Java程序员不会犯错。那么对于广大的Java程序员来说,它们最常犯的几个错误都是什么样的呢?...

启示录是真的
05/25
0
0
Oracle中使用Rownum分页详细例子

Oracle中使用Rownum分页详细例子 这篇文章主要介绍了Oracle中使用Rownum分页详细例子,本文将分别展示使用rownum伪列和row_number()分析函数来完成Oracle数据分页操作的具体使用方法,需要的朋...

流浪的猫666
07/06
0
0
Hibernate QBC 语言

基本查询 以下是HQL/QBC/Native SQL三种查询策略 HQL策略: Java代码 session.createQuery("FROM Category c where c.name like 'Laptop%'"); session.createQuery("FROM Category c where c......

boonya
2015/03/25
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

Spring详解

Spring详解(一)------概述 目录 1、什么是 Spring ? 2、Spring 起源 3、Spring 特点 4、Spring 框架结构 5、Spring 框架特征 6、Spring 优点   本系列教程我们将对 Spring 进行详解的介绍...

DemonsI
12分钟前
0
0
CentOS7系统Nginx安装

1、下载nginx,官方网站https://nginx.org wget https://nginx.org/download/nginx-1.14.0.tar.gz 2、下载Nginx Sticky Module,官方网站https://bitbucket.org/nginx-goodies/nginx-sticky-......

m_lm
16分钟前
0
0
使用zTree树控件(二)

1:treeNode.checked用于判断是勾选还是取消勾选。(treeNode指的是节点)

uug
16分钟前
0
0
export, import 和 export default的区别

ES6的两个功能: export 和 import export 对外输出模块 import 引入(加载)进来一个模块 一、export => import 单个变量 export var name = "lishi" 在其他文件里引用 import {name} f...

Js_Mei
21分钟前
1
0
打造RecyclerView的n级列表

先上效果图: 1.该多级列表的优势: 支持无限级列表展开 基于一个recyclerView实现 可以自定义每一级item的样式,定制化更强 2.设计的思路 数据结构List<ItemBean>,ItemBean类中有变量List<...

WelliJohn
30分钟前
1
1

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部