數據量你造嗎-JAVA分頁

原創地址:   http://www.cnblogs.com/Alandre/  (泥沙磚瓦漿木匠),須要轉載的,保留下! Thanks  java

    學習的心態第一,解行要相應。其實《弟子規》在「餘力學文」當中,一開頭就強調了這一個重點。「不力行,但學文,長浮華,成何人」,這個沒有僥倖的,只要學了不去作,無形當中就會增加傲慢,本身不知道。-<弟子規>spring

Written In The Font

    JAVA-Web 基礎那塊,我本身也準備.搞哪裏,優化哪裏而後帶給你們終結.謝謝sql

    分頁雖易,好卻難.數據量,怎麼辦?apache

Content

    分頁(Paging),就像個切面.能把這個切面好好的放進去也是種nice方式.api

 

第一種:小數據量分頁實現 (可普遍用於 門戶型 網頁快速開發等)app


    這種比較簡單,這邊咱們模擬實現.ide

    字段結構:函數

                   private int pageSize; //每頁有多少條工具

                   private int rowCount; //總行數   post

                   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]

相關文章
相關標籤/搜索