瘋狂

          STANDING ON THE SHOULDERS OF GIANTS
          posts - 481, comments - 486, trackbacks - 0, articles - 1
            BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

          ssh中利用pager-taglib和filter進行分頁

          Posted on 2007-11-16 18:34 瘋狂 閱讀(4853) 評論(14)  編輯  收藏

               在ssh架構中利用pager-taglib和filter根據用戶需求顯示進行分頁,在次將實現一個根據用戶在下拉類表用選擇每頁將要顯示多少行進行分頁
             首先介紹pager-taglib標簽:
           pg:pager【這個標簽用來設置分頁的總體參數】重要參數說明:
           url:分頁的鏈接根地址,pager標簽會在這個鏈接的基礎上附加分頁參數
           items:總記錄數,pager標簽正是根據這個值來計算分頁參數的//需要給它賦上查詢的記錄數
           maxPageItems:每頁顯示的行數,默認為10
           maxIndexPages:在循環輸出頁碼的時候,最大輸出多少個頁碼,默認是10
           
          pg:first【第一頁的標簽】重要參數說明:
           export變量的意義:
           pageUrl - 分頁鏈接URL地址(最重要的export參數)
           pageNumber - 頁碼
           firstItem - 首頁第一行的索引值
           lastItem - 首頁最后一行的索引值
          pg:pre【上一頁標簽】重要參數說明:
           export變量的意義:
           pageUrl - 分頁鏈接URL地址(最重要的export參數)
           pageNumber - 頁碼
           firstItem - 前頁第一行的索引值
           lastItem - 前頁最后一行的索引值
          pg:next【下一頁標簽】重要參數說明:
           export變量的意義:
           pageUrl - 分頁鏈接URL地址(最重要的export參數)
           pageNumber - 頁碼
           firstItem - 下頁第一行的索引值
           lastItem - 下頁最后一行的索引值
          pg:last重要參數說明:
           export變量的意義:
           pageUrl - 分頁鏈接URL地址(最重要的export參數)
           pageNumber - 頁碼
           firstItem - 尾頁第一行的索引值
           lastItem - 尾頁最后一行的索引值
          pg:pages【這個標簽用來循環輸出頁碼信息】重要參數說明:
           export變量的意義:
           pageUrl - 分頁鏈接URL地址(最重要的export參數)
           pageNumber - 頁碼
           firstItem - pageNumber這個頁碼指定的那一頁的第一行的索引值
           lastItem - pageNumber這個頁碼指定的那一頁的最后一行的索引值

                 pager-taglib組件默認的每頁顯示數目為10,相應的屬性是maxPageItems="10",因此我可以將用戶自己的顯示行數放在session內,并將其賦值給maxPageItems就可以實現用戶自己的分頁類型。例如httpRequest.getSession().setAttribute("ps", 10);然后maxPageItems="ps"
             
          下面是一個具體的例子:
                 首先下載pager-taglib-2.0.war ,地址http://jsptags.com/tags/navigation/pager/download.jsp,然后將lib下面的包lib下的jar包放到自己項目的lib下面。
              生成測試表:t_person,其中實體類Person類有id,name,phone屬性,具體在hibernate配置文件中的配置略..。
              創建PagerModel類用于存放從數據庫查詢的所有person,和總記錄數。代碼如下:
           package com.test;
          import java.util.List;
          public class PagerModel {
          private int total;//總記錄數
          private List datas;//所有用戶集合

           ...get和set方法
          }

           下面一個類用于得到每頁個顯示數和用于查詢的首記錄數

          package com.test.filter;

          public class SystemContext {
           private static ThreadLocal<Integer> offset = new ThreadLocal<Integer>();//用于query.setFirstResult(offset)
           private static ThreadLocal<Integer> pagesize = new ThreadLocal<Integer>();//pagesize每頁顯示的行數用于

          query.setMaxResults(pagesize);-----ThreadLocal線程局部變量,就是為每一個使用該變量的線程都提供一個變量值的副本,每一個線程都可以獨立地改變自己的副本,而不會和其它線程的副本沖突,也就是每一個用戶都可以改變自己的每頁顯示的行數而不會影響到其他人
           
           public static void setOffset(int offsetvalue){
            offset.set(offsetvalue);
           } 
           public static int getOffset(){
            Integer ov = offset.get();
            if(ov == null){
             return 0;
            }
            return ov;
           }
           
           public static void setPagesize(int pagesizevalue){
            pagesize.set(pagesizevalue);
           }
           
           public static int getPagesize(){
            Integer ps = pagesize.get();
            if(ps == null){
             return Integer.MAX_VALUE;//將pagesize設置為無窮大,也就是顯示在一頁上
            }
            return ps;
           }
                  public static void removeOffset(){//清除為每個用戶分配的副本
            offset.remove();
           }
                  public static void removePagesize(){
            pagesize.remove();
           }
           
          }
          主要的類PagerFilter:用于設置加載用戶自定義的pagesize和offset
          package com.test.filter;

          import java.io.IOException;

          import javax.servlet.Filter;
          import javax.servlet.FilterChain;
          import javax.servlet.FilterConfig;
          import javax.servlet.ServletException;
          import javax.servlet.ServletRequest;
          import javax.servlet.ServletResponse;
          import javax.servlet.http.HttpServletRequest;


          public class PagerFilter implements Filter {

           public static final String PAGE_SIZE_NAME = "ps";
           
           public void destroy() {
            
           }
           public void doFilter(ServletRequest request, ServletResponse response,
             FilterChain chain) throws IOException, ServletException {
            
            HttpServletRequest httpRequest = (HttpServletRequest)request;
            //設置分頁參數
            SystemContext.setOffset(getOffset(httpRequest));
            SystemContext.setPagesize(getPagesize(httpRequest));
            
            try{
             chain.doFilter(request, response);
            }finally{
             SystemContext.removeOffset();
             SystemContext.removePagesize();
            }  
           } 
           private int getOffset(HttpServletRequest httpRequest){
            int offset = 0;
            try {
             offset = Integer.parseInt(httpRequest.getParameter("pager.offset"));//得到標簽自己計算出的pager.offset
            } catch (Exception ignore) {
            }
            return offset;
           } 
           //獲取每頁顯示的行數
           private int getPagesize(HttpServletRequest httpRequest){
            String pageSize = httpRequest.getParameter("pagesize");//得到用戶自己的每頁顯示的行數
            if(pageSize != null){
             Integer ps;
             try {
              ps = Integer.parseInt(pageSize);
              httpRequest.getSession().setAttribute(PAGE_SIZE_NAME, ps);
             } catch (Exception ignore) {

             }
            }
            Integer pagesize = (Integer)httpRequest.getSession().getAttribute(PAGE_SIZE_NAME);
            if(pagesize == null
          ){//如果用戶沒有設置就每日顯示10行,并將其放入session供以便在顯示頁面賦值給maxPageItems使用
             httpRequest.getSession().setAttribute(PAGE_SIZE_NAME, 10);
             return 10;
            }else{
             return pagesize;
            }
           }

           public void init(FilterConfig arg0) throws ServletException {
           
           }

          }
          在web.xml中配置:
          <filter>
               <filter-name>pagerfilter</filter-name>
               <filter-class>com.test.filter.PagerFilter</filter-class>
             </filter>
             <filter-mapping>
              <filter-name>pagerfilter</filter-name>
              <url-pattern>/*</url-pattern>
             </filter-mapping>

           建立AbstractManager類用于封裝查詢數據庫的細節,管理類可以通過searchPaginated(String hql)就可以得到PagerModel :

               public class AbstractManager extends HibernateDaoSupport {
           
                 public PagerModel searchPaginated(String hql){
            return searchPaginated(hql,offset,pagesize);
           }
           public PagerModel searchPaginated(String hql,int offset,int pagesize){
            
            //獲取總記錄數
            String countHql = getCountQuery(hql);
            Query query = getSession().createQuery(countHql);
            if(params != null && params.length > 0){
             for(int i=0; i<params.length; i++){
              query.setParameter(i, params[i]);
             }
            }
            int total = ((Long)query.uniqueResult()).intValue();
            
            //獲取當前頁的結果集
            query = getSession().createQuery(hql);
            if(params != null && params.length > 0){
             for(int i=0; i<params.length; i++){
              query.setParameter(i, params[i]);
             }
            }
            query.setFirstResult(SystemContext.getOffset());//通過SystemContext得到Offset
            query.setMaxResults(SystemContext.getPagesize();//通過SystemContext得到pagesize
            List datas = query.list();
            PagerModel pm = new PagerModel();
            pm.setDatas(datas);
            pm.setTotal(total);
            return pm;
           }
           //根據HQL語句,獲得查找總記錄數的HQL語句如:select .... from ...轉換為:select count(*) from ....
           private String getCountQuery(String hql){
            int index = hql.indexOf("from");
            if(index != -1){
             return "select count(*) " + hql.substring(index);
            }
            throw new SystemException("無效的HQL查詢語句!");
           }
          }
             //下面是具體管理類//得到分頁數據PagerModel:
          public class PersonManagerImpl extends AbstractManager implements PersonManager {//PersonManager為一個interface
                public PagerModel searchPersons() {
            PagerModel pm = new PagerModel();
            String hql = "select p from Person p";
            return this.searchPaginated(hql);
           }
          }
              創建訪問頁面index.jsp
          主要代碼:<a href="person.do">用戶分頁類表</a>
              相應的action頁面:主要代碼:

          public class PersonAction extends DispatchAction {

           private PersonManager personManager;//利用spring注入person管理類
           @Override
           protected ActionForward unspecified(ActionMapping mapping, ActionForm form,
             HttpServletRequest request, HttpServletResponse response)
             throws Exception {
            
            PagerModel pm = personManager.searchPersons();
            request.setAttribute("pm", pm);
            return mapping.findForward("index");//通過配置文件轉到list.jsp
           }
                  public void setPersonManager(PersonManager personManager) {
            this.personManager = personManager;
           }

          }
          顯示頁面:list.jsp
          <%@ taglib prefix="pg"  uri="http://jsptags.com/tags/navigation/pager" %>//引入
          ...
          <script type="text/javascript">
          function selectPagesize(field){
           document.location.href = document.all.firstpageurl.href + "&pagesize="+field.value
          ;//得到用戶從下拉列表選擇的每頁顯的行數,并刷新到轉到首頁
          }
          </script>
          ....

          <table>
                    <!-- 列表標題欄 -->

                 <tr bgcolor="#EFF3F7" class="TableBody1">
                 
                  <td >姓名</td>
                  <td >電話</td>
                         </tr>
                    <!-- 列表數據欄 -->
                    <c:forEach items="${pm.datas }" var="person">
                 <tr>
               <td >${person.name }</td>
                     <td >${person.phone }</td>
                        </tr>
                  </c:forEach>
                </table>
                <TABLE>
                  <TBODY>
                    <TR>
                      <TD>
           <!-- 分頁導航條 -->
          <pg:pager url="person.do" items="${pm.total}" export="currentPageNumber=pageNumber" maxPageItems="${ps}">//得到session范圍內的每頁顯示的行數
           <pg:first>
            <a href="${pageUrl}" id="firstpageurl">首頁</a>
           </pg:first>
           <pg:prev>
           <a href="${pageUrl }">前頁</a>
           </pg:prev>
           <pg:pages>
            <c:choose>
             <c:when test="${currentPageNumber eq pageNumber}">
              <font color="red">${pageNumber }</font>//當前頁號不顯示鏈接

             </c:when>
             <c:otherwise>
              <a href="${pageUrl}">${pageNumber }</a>
             </c:otherwise>
            </c:choose>
           </pg:pages>
           <pg:next>
           <a href="${pageUrl }">后頁</a>
           </pg:next>
           <pg:last>
           <a href="${pageUrl }">尾頁</a>
           </pg:last>
          </pg:pager>
           <!-- 用戶選擇每頁顯示行數下拉列表 -->
          每頁顯示
          <select name="pagesize" onchange="selectPagesize(this)" >
          <c:forEach begin="5" end="50" step="5" var="i">
           <option value="${i}"
           <c:if test="${ps eq i }">selected</c:if>
           >${i}</option>
          </c:forEach>
          </select>行
                </TD>
                    </TR>
                  </TBODY>
                </TABLE>

          實現圖如下:

          評論

          # re: ssh中利用pager-taglib和filter進行分頁  回復  更多評論   

          2007-11-16 23:05 by 專注JAVA開源項目
          收藏

          # re: ssh中利用pager-taglib和filter進行分頁  回復  更多評論   

          2007-11-17 07:47 by ltnetwork
          寫得很好,我用的就是這個分頁標簽

          # re: ssh中利用pager-taglib和filter進行分頁  回復  更多評論   

          2007-11-17 07:53 by ltnetwork
          pager-taglib默認的是查找全部記錄到內存,這樣的話數據量大的話會很累,可不可以限制查詢返回的記錄數?

          # re: ssh中利用pager-taglib和filter進行分頁  回復  更多評論   

          2007-11-17 09:26 by freeman1984
          @ltnetwork
          pager-taglib并沒有和數據庫打交道,它只是根據你給它的items(記錄總數值)和設置的每頁顯示的記錄數以及它自己計算出的每頁的首記錄來進行計算分多少頁,而items并沒有要求和數據庫的總記錄數對應,比如:你的數據有100條,而你給items設置item=“200”,假如每頁顯示100條,他就會計算出要顯示2頁,而不是1頁。
          它根據pageUrl標簽得到頁面的url地址,而這個地址例如http://localhost:8888/test/person.do?pager.offset=0就代表第一頁,如果你設置的每頁顯示5行的話第二頁的地址就是http://localhost:8888/test/person.do?pager.offset=5,而這個pager.offset(每頁首記錄)是他自己傳遞的,真正和數據庫打交道的是person.do對應的action以及你的manager做的,你的manager得到每頁顯示的pagesize和通過httpRequest.getParameter("pager.offset"))得到每頁的首記錄進行查詢分頁。

          # re: ssh中利用pager-taglib和filter進行分頁[未登錄]  回復  更多評論   

          2007-11-17 09:33 by jurafish
          好像不能跳轉到制定頁面:(

          # re: ssh中利用pager-taglib和filter進行分頁  回復  更多評論   

          2007-12-31 02:15 by zhoudq
          您好,能把例子發我份嗎?謝謝
          zhdqCN@gmail.com

          # re: ssh中利用pager-taglib和filter進行分頁  回復  更多評論   

          2008-04-15 08:43 by 王建
          您好,能把例子發我份嗎?謝謝
          email : wangjian3q@163.com

          # re: ssh中利用pager-taglib和filter進行分頁[未登錄]  回復  更多評論   

          2008-07-23 10:27 by aaa
          我想請問一下AbstractManager類中的params數組變量是從哪里來的.從天上飛下來的?

          # re: ssh中利用pager-taglib和filter進行分頁  回復  更多評論   

          2008-12-08 14:13 by javaQuestion
          感謝你的無私的指導!能否發一份源碼給我,十分謝謝!熱愛java的人。
          E-Mail:lwsletter@126.com

          # re: ssh中利用pager-taglib和filter進行分頁  回復  更多評論   

          2009-10-29 19:39 by 無水的魚
          你好 最近在學校學習Hibernate 能發份給我么 感謝!

          # re: ssh中利用pager-taglib和filter進行分頁  回復  更多評論   

          2009-10-29 19:40 by 無水的魚
          你好 最近在學校學習Hibernate 能發份給我么 感謝!261630172@qq.com

          # re: ssh中利用pager-taglib和filter進行分頁  回復  更多評論   

          2009-11-02 15:59 by 咖啡妝
          @無水的魚
          源代碼都很久了好像不見了,對不起哦

          # re: ssh中利用pager-taglib和filter進行分頁  回復  更多評論   

          2010-09-27 16:22 by 將計就計
          如果有a標簽 分頁的鏈接 怎么不讓它改變呢

          # re: ssh中利用pager-taglib和filter進行分頁[未登錄]  回復  更多評論   

          2011-05-09 14:24 by spring
          請問,單擊第二頁的記錄時,怎么還能返回到第二頁啊,也就是pager.offset的值應該在action里怎么設置啊

          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          主站蜘蛛池模板: 南木林县| 南丰县| 黄浦区| 桦甸市| 玛曲县| 吴江市| 洛扎县| 明星| 宁波市| 房产| 五常市| 佳木斯市| 德阳市| 宝兴县| 巩留县| 丰台区| 睢宁县| 舟曲县| 电白县| 绥滨县| 军事| 稻城县| 珲春市| 龙胜| 灵武市| 周宁县| 宜宾市| 泽州县| 六安市| 贵港市| 广灵县| 揭东县| 定兴县| 桐柏县| 元阳县| 岗巴县| 桃园县| 洱源县| 通渭县| 中阳县| 铜陵市|