【Java EE 學習 57】【酒店會員管理系統之分頁模板書寫】

分頁一直是一個比較麻煩的問題,特別是在我作的這個系統中更是有大量的分頁,爲了應對該問題,特意寫了一個模板以方便代碼重用,該模板包括後臺分頁的模板、前端顯示的模板兩部分。css

1、分頁分析前端

  分頁須要三種類型的參數:sql

  1.系統啓動以後就可以肯定的參數,好比每頁顯示多少條數據pageSize,分頁長度:elementLength瀏覽器

  2.瀏覽器動態請求的參數這種狀況分爲兩種:帶有請求的頁碼(requestPage)和不帶有請求的頁碼。服務器

    因爲後臺的分頁代碼是重用的,因此第一次請求的時候就須要帶上請求的頁碼,若是不帶上請求的頁碼默認是1,這須要後臺代碼進行判斷。jsp

    

  3.服務器響應的數據,好比首頁碼(startIndex)、尾頁碼(endIndex)、總共的頁碼(totalPages)、當前的頁碼(currentPage=requestPage),固然還有響應的數據。大數據

2、前端頁面this

  發起分頁請求的多是一個超連接觸發,也有多是一個查詢按鈕觸發,請求的方法都是同一個方法。spa

  1.超連接觸發hibernate

      

  2.查詢按鈕觸發

   

  對於超連接觸發的,能夠直接訪問action,可是查詢按鈕觸發的卻須要作一些動做才行。

  (1)表單設置隱藏域,設置默認請求頁碼或者大多部分提供給js進行更改請求頁碼並提交給Action。

<s:hidden name="requestPage" value="1"></s:hidden>

  (2)不能直接提交,須要先經過js進行設置:

/*
 *多條件查詢和分頁頁面使用的js 
 */
$().ready(function(){
    $("#pageSplit a").each(function(){
        $(this).unbind("click");
        $(this).bind("click",function(){
            var requestPage=$(this).attr("href").split("requestPage=")[1];
            $("input[name='requestPage']").val(requestPage);
            $("form").submit();
            return false;
        });
    });
    $("#query").unbind("click");
    $("#query").bind("click",function(){
        $("form").submit();
    });
});
#pageSplit a是前端的jsp(struts2)分頁模板,後邊介紹。

 3.前端顯示的jsp分頁模板(struts2)

<div id="pageSplit">
            <s:a>首頁
                <s:param name="requestPage" value="1"></s:param>
            </s:a>
            <s:a>上一頁
                <s:param name="requestPage" value="#requestPage-1>0?#requestPage-1:1"></s:param>
            </s:a>
            <s:iterator var="page" begin="%{#startIndex}" end="%{#endIndex}">
                <s:if test="#page==#requestPage">
                    <s:a cssStyle="background-color: #91C0E3;">
                        <s:param name="requestPage" value="#page"></s:param>
                        <s:property value="#page"/>
                    </s:a>
                </s:if>
                <s:else>
                    <s:a>
                        <s:param name="requestPage" value="#page"></s:param>
                        <s:property value="#page"/>
                    </s:a>
                </s:else>
            </s:iterator>
            <s:if test="%{#totalPages>#endIndex}">
                ......
                <s:a>
                    <s:param name="requestPage" value="#endIndex+1"></s:param>
                共有
                <s:property value="%{#totalPages}"/></s:a>
            </s:if>
            <s:else>
                <s:a>
                    <s:param name="requestPage" value="%{#totalPages}"></s:param>
                共有
                <s:property value="%{#totalPages}"/></s:a>
            </s:else>
            <s:a>
                下一頁
                <s:param name="requestPage" value="#requestPage+1>#totalPages?#totalPages:#requestPage+1"></s:param>
            </s:a>
            <s:a>
                尾頁
                <s:param name="requestPage" value="#totalPages"></s:param>
            </s:a>
        </div>

    結合的css樣式模板

#pageSplit{
    margin-top:7px;
    margin-bottom:7px;
    font-size: 14px;
    text-align: center;
}
#pageSplit a{
    display: inline-block;
    background-color:#CEE5EA;
    border :1px solid ;
    padding-top: 3px;
    padding-bottom: 3px;
    padding-left: 7px;
    padding-right:7px;
    color: #004779;
    text-decoration: none;
}
#pageSplit a:HOVER {
    background-color: #ADD8E5;
}
#query{
    font-size:12px;
    width: 50px;
    height: 24px;    
    text-align: center;
    margin: 0px;
}

2、後臺分頁邏輯實現

  1.經過監聽器肯定初始化的兩個參數:pageSize和elementLength

  首先將參數放到配置文件中:init.properties

#every pages show 12 datas
pageSize=10
#show the choose length prePage,1,2,3,4,5,6,7,8 nextPage
splitPageLength=5

  監聽器獲取

InputStream is=MyServletContextListener.class.getClassLoader().getResourceAsStream("init.properties");
Properties initProperties=new Properties();
initProperties.load(is);
PageSplitConfig.splitPageLength=Integer.parseInt(initProperties.getProperty("splitPageLength"));
PageSplitConfig.pageSize=Integer.parseInt(initProperties.getProperty("pageSize"));
            

  這樣就將兩個參數封裝到了PageSplitConfig類中:

public class PageSplitConfig {
    //首先是每頁顯示多少條數據
    public static Integer pageSize;
    //分頁的長度
    public static Integer splitPageLength;
}

  2.Action中進行分頁的邏輯控制:

  以showAllCards方法爲例:

public String showAllCards(){
        //預配置代碼
        /*Collection<Card>list=cardService.getAllCards();
        ActionContext.getContext().put("cardlist", list);*/
        Collection<CredentialType> credentialTypes=credentialTypeService.getAllCredentialTypes();
        List<String> allCredentialTypes=new ArrayList<String>();
        for(CredentialType temp:credentialTypes){
            allCredentialTypes.add(temp.getCredentialTypeName());
        }
        ActionContext.getContext().put("credentialTypes", allCredentialTypes);
        //預配置代碼結束
        
        //獲取請求參數開始
        HttpServletRequest request=ServletActionContext.getRequest();
        String cardId=request.getParameter("cardId");
        if(cardId==null||"".equals(cardId)){
            ActionContext.getContext().put("cardId", "");
        }else{
            ActionContext.getContext().put("cardId", cardId);
        }
        String userName=request.getParameter("userName");
        if(userName==null||"".equals(userName)){
            ActionContext.getContext().put("userName", "");
        }else{
            ActionContext.getContext().put("userName",userName);
        }
        String typeofcredential=request.getParameter("typeofcredential");
        if(typeofcredential==null||"".equals(typeofcredential)||"''".equals(typeofcredential)){
            ActionContext.getContext().put("typeofcredential", "");
        }else{
            ActionContext.getContext().put("typeofcredential", typeofcredential);
        }
        String sex=request.getParameter("sex");
        if(sex==null||"".equals(sex)||"不限".equals(sex)){
            ActionContext.getContext().put("sex", "不限");
        }else{
            ActionContext.getContext().put("sex", sex);
        }
        String integral=request.getParameter("integral");
        if(integral==null||"".equals(integral)){
            ActionContext.getContext().put("integral", "");
        }else{
            ActionContext.getContext().put("integral", integral);
        }
        //獲取請求參數結束
        
        //計算分頁參數開始
        String requestPage=request.getParameter("requestPage");
        if(requestPage==null||"".equals(requestPage.trim())){
            requestPage="1";
        }
        System.out.println("requestPage:"+requestPage);
        Collection<Card>cards=cardService.getCardsByMN(Integer.parseInt(requestPage),cardId,userName,
                typeofcredential,sex,integral);
        int totalLines=this.cardService.getTotalLines(Integer.parseInt(requestPage),cardId,userName,
                typeofcredential,sex,integral);
        System.out.println("totalLines:"+totalLines);
        PageSplitData.requestPage=Integer.parseInt(requestPage);
        PageSplitData.calculate(totalLines);
        //計算分頁參數結束
        
        System.out.println("startIndex:"+PageSplitData.startIndex);
        System.out.println("endIndex:"+PageSplitData.endIndex);
        System.out.println("totalPages:"+PageSplitData.totalPages);
        System.out.println("查詢到的會員數量:"+cards.size());
        ActionContext.getContext().put("startIndex",PageSplitData.startIndex);
        ActionContext.getContext().put("endIndex", PageSplitData.endIndex);
        ActionContext.getContext().put("requestPage",PageSplitData.requestPage);
        ActionContext.getContext().put("totalPages",PageSplitData.totalPages);
        ActionContext.getContext().put("employees", cards);
        ActionContext.getContext().put("cardlist", cards);
        return    listAction; 
    }

  首先須要調用Service方法獲取數據和數據總量

Collection<Card>cards=cardService.getCardsByMN(Integer.parseInt(requestPage),cardId,userName,
                typeofcredential,sex,integral);
int totalLines=this.cardService.getTotalLines(Integer.parseInt(requestPage),cardId,userName,
                typeofcredential,sex,integral);

  (1)獲取指定分頁數據的方法:

public Collection<Card> getCardsByMN(int requestPage, String cardId,
            String userName, String typeofcredential, String sex,
            String integral) {
        int m=(requestPage-1)*PageSplitConfig.pageSize;
        int n=PageSplitConfig.pageSize;
        String sql="from Card where 1=1 ";
        if(cardId!=null&&!"".equals(cardId.trim())){
            sql=sql+" and cardId='"+cardId.trim()+"'";
        }
        if(userName!=null&&!"".equals(userName.trim())){
            sql=sql+" and userName='"+userName.trim()+"'";
        }
        if(typeofcredential!=null&&!"".equals(typeofcredential.trim())&&!"''".equals(typeofcredential.trim())){
            sql=sql+" and credentialType.credentialTypeName='"+typeofcredential.trim()+"'";
        }
        if(sex!=null&&!"".equals(sex.trim())&&!"不限".equals(sex.trim())){
            sql=sql+" and sex='"+sex+"'";
        }
        if(integral!=null&&!"".equals(integral.trim())){
            sql=sql+" and integral='"+integral.trim()+"'";
        }
        return this.cardDao.getAllCards(sql,m,n);
    }

  該方法會調用DAO方法:

public Collection<Card> getAllCards(String sql, int m, int n) {
        Query query=this.hibernateTemplate.getSessionFactory().openSession().createQuery(sql);
        query.setFirstResult(m);
        query.setMaxResults(n);
        return query.list();
    }

  (2)獲取全部數據總量的方法:

public int getTotalLines(int requestPage, String cardId, String userName,
            String typeofcredential, String sex, String integral) {
        String sql="from Card where 1=1 ";
        if(cardId!=null&&!"".equals(cardId.trim())){
            sql=sql+" and cardId='"+cardId.trim()+"'";
        }
        if(userName!=null&&!"".equals(userName.trim())){
            sql=sql+" and userName='"+userName.trim()+"'";
        }
        if(typeofcredential!=null&&!"''".equals(typeofcredential.trim())&&!"".equals(typeofcredential.trim())){
            sql=sql+" and credentialType.credentialTypeName='"+typeofcredential.trim()+"'";
        }
        if(sex!=null&&!"".equals(sex.trim())&&!"不限".equals(sex.trim())){
            sql=sql+" and sex='"+sex.trim()+"'";
        }
        if(integral!=null&&!"".equals(integral.trim())){
            sql=sql+" and integral='"+integral.trim()+"'";
        }
        return this.cardDao.getAllCards(sql).size();
    }

    調用DAO方法實現:

public Collection<Card> getAllCards(String sql) {
        return this.hibernateTemplate.getSessionFactory().openSession().createQuery(sql).list();
    }

  (3)最重要的分頁邏輯的實如今SplitPageData類中:

public class PageSplitData {
    //該條數據應該在調用響應方法以前賦值
    public static Integer requestPage;    //請求以後應該強調顯示的頁碼,即響應以後的當前頁或者響應時的響應頁碼。
    public static Integer startIndex;            //起始頁碼
    public static Integer endIndex;            //最後頁碼
    public static Integer totalPages;        //一共有多少頁
    
    /**
     * 
     * @param total
     */
    public static void calculate(int totalLines){
        //每頁顯示多少條數據
        int pageSize=PageSplitConfig.pageSize;
        //分頁長度
        int splitPageLength=PageSplitConfig.splitPageLength;
        //已經獲得了數據一共有多少條:totalLines 和 請求頁 requestPage
        
        //獲得總頁數
        totalPages=totalLines/pageSize+(totalLines%pageSize==0?0:1);
        
        //計算startIndex和endIndex的關鍵原則就是endIndex-startIndex的結果是splitPageLength-1
        if(splitPageLength%2==0){//分頁長度是偶數,爲了讓當前頁在中間,採用前多後少的分頁方法
            //這種狀況下splitPageLength/2+splitPageLength/2==splitPageLength
            startIndex=requestPage-(splitPageLength/2+1);//正常狀況(針對大數據)
            endIndex=requestPage+(splitPageLength/2);//特殊狀況(針對大數據)
        }else{//分頁長度是奇數
            //這種狀況下splitPageLength/2+splitPageLength/2=splitPageLength-1,符合以前說的原則
            startIndex=requestPage-(splitPageLength/2);//這樣就正好了
            endIndex=requestPage+(splitPageLength/2);//正好
        }
        if(startIndex<=0){
            startIndex=1;
            if((startIndex+splitPageLength-1)>totalPages){
                endIndex=totalPages;
            }else{
                endIndex=startIndex+splitPageLength-1;
            }
        }else{//正常狀況
            if(endIndex>totalPages){
                endIndex=totalPages;
                if((endIndex-(splitPageLength-1))<=0){
                    startIndex=1;
                }else{
                    startIndex=endIndex-(splitPageLength-1);
                }
            }else{
                //正常狀況,不作處理
            }
        }
        //須要傳遞的幾個參數都計算完畢
    }

    public static Integer getRequestPage() {
        return requestPage;
    }

    public static Integer getStartIndex() {
        return startIndex;
    }

    public static Integer getEndIndex() {
        return endIndex;
    }

    public static Integer getTotalPages() {
        return totalPages;
    }
}

3、總結

  該分頁模板須要的參數經過三種途徑傳到PageSplitData類中

  1.監聽器傳遞pageSize和elementLength兩個參數

  2.經過set方法設置請求頁requestPage

  3.直接傳遞totalLines

  計算結果包括

  1.首頁碼:startIndex

  2.尾頁碼:endIndex

  3.總頁數:totalPages

  

 

#pageSplit a
相關文章
相關標籤/搜索