displayTags大數據量分頁導航

 

李楠注:
    這個內容我還沒有測試過,打算以後分別用mysql,mssql,oracle10g測試一下,
數據量分別爲1萬,2萬,10萬,100萬。這裏先把此文檔保存下來。
    關注這個內容,主要是這個功能要經常使用,並且,每個框架的實現都不相同(比如hibernate,ibatis)。
這次,是因爲我在分析ibatis的框架,而聽說ibatis實現的PaginatedList接口在數據量不超過2萬的時候,
可以使用,但遇到大數據量的時候會有問題。據說在一個30萬行的表裏翻頁,
一次select用了363.031second。如果真是這樣的話,只好自己實現這個接口了。
    以下,是文章的內容:
----------------------------------------------

由於displayTag只處理數據的顯示,傳遞給他多少數據,它會根據數據的記錄數及其每頁顯示多少計算出需要的頁數,但是在處理大數據量集合的時候,會遇到問題,就是將所有的數據傳遞給displayTag表格顯示標籤變得不現實也沒有必要,如何既能夠用到dispalyTag強大的顯示功能,用能夠很好的處理大數據量的
顯示和分頁功能呢?


當我遇到這個問題的時候,感到無從下手,因爲我當時並不是很熟悉displaytag,更不要提它的深層次的處理機制問題了,嘿嘿!於是我就開始在羣裏請教高人,未果,無奈之餘我只有藉助網絡,哈,我不停的變換關鍵詞進行搜索,結果發現不止是我一個人遇到此問題啊,那是千千萬萬啊(一點都不誇張)!在那些五花八門的答案中我開始篩選,實驗。。。

最終,根據displayTag官方文檔的推薦和網友們的建議,我做開始瞭解決這個問題的嘗試(雖然之前我遇到這個問題的時候,就先請教了我的一個同事,但他給我的建議我感覺太麻煩了,改動比較大,於是就下決心一定自己解決這個問題啦!)

首先我瞭解到displaytag1.0實在是太傻了,每次分頁還需要將所有數據一次載入,效率低到無法忍受:)而displaytag1.1就不同了,1.1版最大的改進可以說是終於支持了大家期待以久的分次加載功能了,想顯示多少數據就載入多少數據.1.1版本支持兩種方式的分頁,第一種是實現其org.displaytag.pagination.PaginatedList 接口,第二種是在頁面和後臺同時做修改來實現分頁功能.在網上關於第二種分頁的使用方法介紹的非常多,而且官方文檔上面寫的也比較詳細,所以在這裏我主要介紹自己是如何使用第一種方式進行分頁的,且這種方式也是官方推薦分頁方式:

首先寫一個org.displaytag.pagination.PaginatedList 接口的實現類:
//package com.greatroad.webapp.paging;

import java.util.List;

import org.displaytag.pagination.PaginatedList;
import org.displaytag.properties.SortOrderEnum;

/**
* PaginatedListImpl
* User: zhangyd
* Date: 2007-10-20
* Time: 20:35:18
*
* totalNum 所有條目數目
* currentPage 當前所在頁號
* objectsPerPage 每頁顯示條數
* list 此頁所需要顯示的數據
*/
public class PaginatedListHelper implements PaginatedList{
      private List list;
      private int pageNumber = 1;
      private int objectsPerPage = 20;
      private int fullListSize = 0;
      private String sortCriterion;
      private SortOrderEnum sortDirection;
      private String searchId;

      public List getList() {
          return list;
      }

      public void setList(List list) {
          this.list = list;
      }

      public int getPageNumber() {
          return pageNumber;
      }

      public void setPageNumber(int pageNumber) {
          this.pageNumber = pageNumber;
      }

      public int getObjectsPerPage() {
          return objectsPerPage;
      }

      public void setObjectsPerPage(int objectsPerPage) {
          this.objectsPerPage = objectsPerPage;
      }

      public int getFullListSize() {
          return fullListSize;
      }

      public void setFullListSize(int fullListSize) {
          this.fullListSize = fullListSize;
      }

      public String getSortCriterion() {
          return sortCriterion;
      }

      public void setSortCriterion(String sortCriterion) {
          this.sortCriterion = sortCriterion;
      }

      public SortOrderEnum getSortDirection() {
          return sortDirection;
      }

      public void setSortDirection(SortOrderEnum sortDirection) {
          this.sortDirection = sortDirection;
      }

      public String getSearchId() {
          return searchId;
      }

      public void setSearchId(String searchId) {
          this.searchId = searchId;
      }

}
然後在使用的時候只需要創建此類的一個實例,且將所需要的參數通過set方法賦值進去就可以了,比如我在XXXController.java中是這樣實現的(注意加粗的部分):

package com.greatroad.webapp.action;

import java.text.SimpleDateFormat;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.displaytag.pagination.PaginatedList;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;

import com.greatroad.Constants;
import com.greatroad.model.Station;
import com.greatroad.service.CardhistorydataManager;

import com.greatroad.service.StationManager;
import com.greatroad.webapp.paging.PaginatedListHelper;

public class CardhistorydataController implements Controller {
private final Log log = LogFactory.getLog(CardhistorydataController.class);

private CardhistorydataManager cardhistorydataManager = null;

public void setCardhistorydataManager(
     CardhistorydataManager cardhistorydataManager) {
    this.cardhistorydataManager = cardhistorydataManager;
}

private StationManager stationManager = null;

public void setStationManager(StationManager stationManager) {
    this.stationManager = stationManager;
}

public ModelAndView handleRequest(HttpServletRequest request,
                                        HttpServletResponse response)
      throws Exception {
          if (log.isDebugEnabled()) {
              log.debug("entering 'handleRequest' method...");
          }

          Object[] o = new Object[4];
          String personId = request.getParameter("person");
          String d1 = request.getParameter("starttime");
          String d2 = request.getParameter("endtime");
       
          SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
       
          if(personId!=null && personId.length()>0)
           o[0] = personId;
          if(d1!=null && d1.length()>0)
           o[1] = sdf.parse(d1);
          if(d2!=null && d2.length()>0)
           o[2] = sdf.parse(d2);
// ///////////////////////////////////////////////////////
          Station station = new Station();
          String stationId = request.getParameter("stationname");
          if(stationId!=null && stationId.length()>0){
           station = stationManager.getStation(stationId);
           o[3] = stationId;
           request.setAttribute("Stationid", stationId);
          }
           List stationList = stationManager.getStations(null);
           if(stationList != null && stationList.size()>0){
            request.setAttribute("stationlist", stationList);
           }
// /////////////////////////////////////////////////////////////////////////////
        /*
      * 其中request中的page參數爲displaytag中的默認當前頁數,當然也可以使用*TableTagParameters.SORT_AMOUNT_PAGE來表示當前頁數
      */
        int pageSize;
        if (request.getParameter("pageSize") != null
          && !"".equals(request.getParameter("pageSize"))) {
         pageSize = Integer.parseInt(request.getParameter("pageSize"));
        } else {
         pageSize = 15;
        }

        int page = 1;
        if (request.getParameter("page") != null
          && !"".equals(request.getParameter("page"))) {
         page = Integer.parseInt(request.getParameter("page"));
        } else {
         page = 1;
        }

        int fromIndex = (page - 1) * pageSize;
//      int toIndex = fromIndex + pageSize;
        int toIndex = pageSize;
        // 獲得每次查詢的總記錄數
        int ListSize = cardhistorydataManager.countListSize(o);//DAO中實現

        // 此頁要顯示的list數據
        List cardhistorydatas = null;

        if (ListSize > 0) {
         cardhistorydatas = cardhistorydataManager.getCardhistorydatas(o, fromIndex, toIndex);//DAO中實現
        } else {
         cardhistorydatas = null;
        }
        PaginatedList paginaredList = new PaginatedListHelper();
        ((PaginatedListHelper) paginaredList).setPageNumber(page);
        if (cardhistorydatas != null && ListSize != 0) {
         // System.out.println("getFullListSize: " + ListSize);
         // 總共有多少數據,他會根據所有數目和每頁數目自動統計頁數
         ((PaginatedListHelper) paginaredList).setFullListSize(ListSize);
         ((PaginatedListHelper) paginaredList).setObjectsPerPage(pageSize);
         ((PaginatedListHelper) paginaredList).setList(cardhistorydatas);
        } else {
         ((PaginatedListHelper) paginaredList).setFullListSize(0);
         ((PaginatedListHelper) paginaredList).setList(null);
        }
        // 如果你只設定這幾個參數,那麼其餘的參數將會默認爲你實現類中所賦的初值
        // 最後,你還需要將這個實例放入到request或session中去,好讓displaytag知道這個是外部分頁
//        request.setAttribute("cardhistorydataList", paginaredList);
////////////////////////////////////////////////////////////////////////////////

          return new ModelAndView("cardhistorydataList", Constants.CARDHISTORYDATA_LIST, paginaredList);
      }
}
當然還有相關的一些地方需要改動,如果你能做的這一步,其餘的那些已經不是問題了^!^另外再強調一點:頁面無需任何改動哦!

參考文獻:http://displaytag.sourceforge.net/11/

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章