zoukankan      html  css  js  c++  java
  • 【Java EE 学习 57】【酒店会员管理系统之分页模板书写】

    分页一直是一个比较麻烦的问题,特别是在我做的这个系统中更是有大量的分页,为了应对该问题,特地写了一个模板以方便代码重用,该模板包括后台分页的模板、前端显示的模板两部分。

    一、分页分析

      分页需要三种类型的参数:

      1.系统启动之后就能够确定的参数,比如每页显示多少条数据pageSize,分页长度:elementLength

      2.浏览器动态请求的参数这种情况分为两种:带有请求的页码(requestPage)和不带有请求的页码。

        由于后台的分页代码是重用的,所以第一次请求的时候就需要带上请求的页码,如果不带上请求的页码默认是1,这需要后台代码进行判断。

        

      3.服务器响应的数据,比如首页码(startIndex)、尾页码(endIndex)、总共的页码(totalPages)、当前的页码(currentPage=requestPage),当然还有响应的数据。

    二、前端页面

      发起分页请求的可能是一个超链接触发,也有可能是一个查询按钮触发,请求的方法都是同一个方法。

      1.超链接触发

          

      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;
    }

    二、后台分页逻辑实现

      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;
        }
    }

    三、总结

      该分页模板需要的参数通过三种途径传到PageSplitData类中

      1.监听器传递pageSize和elementLength两个参数

      2.通过set方法设置请求页requestPage

      3.直接传递totalLines

      计算结果包括

      1.首页码:startIndex

      2.尾页码:endIndex

      3.总页数:totalPages

      

    #pageSplit a
  • 相关阅读:
    利用书签栏作插入时失败告终
    组以逗号分隔的子串及跨平update join
    ms_sql:drop and create a job
    why dicePlayer cannot player with defy mb526
    好像国庆三天是可以加班工资计了
    msssql 用numberic(38)替代int去解决int不够的问题
    C#的switch与二维数组.....
    某牛人所留的联系方式
    封装对象类
    数据库访问小列题
  • 原文地址:https://www.cnblogs.com/kuangdaoyizhimei/p/4944743.html
Copyright © 2011-2022 走看看