隨筆 - 170  文章 - 536  trackbacks - 0
          <2008年1月>
          303112345
          6789101112
          13141516171819
          20212223242526
          272829303112
          3456789

          常用鏈接

          我參與的團隊

          隨筆分類(103)

          搜索

          •  

          積分與排名

          • 積分 - 414317
          • 排名 - 135

          最新評論

          閱讀排行榜

          好久沒有寫點東西了,這次想把JSF中的分頁系列文章再擴充一點,說明一下查詢和分頁結合的情況,當我們把查詢條件和查詢結果放到一個頁面上時,查詢還是非常容易實現的,甚至不需要我們手工去從數據庫中查詢。

          在本系列文章中的第二篇中,介紹了一種 Load On Demand的方式,我們在這里需要繼續利用這種方式,并對其做一些小小的擴展。這里我們使用 Hibernate3 作為持久化方案。

          簡單的介紹一下應用情景,一個系統中包含了一些 Customer 的信息,我們需要對其進行查詢并對查詢結果進行分頁。

          首先處理條件查詢的情況,通常會根據 VO 中的字段進行 like 型查詢,有時候時間或數字之類的會使用Between查詢,因為查詢條件一般不會很復雜,在這里,使用 Hibernate3 中的 Criteria 查詢來處理這樣的情況,我們把所有的查詢條件通過 Customer 這個 VO 傳進來,然后只對非空字段進行 like 查詢,我們用到這樣的方法。

          public ?List?queryByConditions(Customer?customer,? int ?startRow,? int ?pageSize)
          {
          ?Criteria?criteria?
          = ?getSession().createCriteria(Customer. class );
          ?
          if ?( ! StringUtils.isEmpty(customer.getCustomerName()))
          ?{
          ??criteria.add(QueryUtils.getCriteriaParam(
          " customerName " ,?customer.getCustomerName()));
          ?}
          ?
          if ?( ! StringUtils.isEmpty(customer.getAddress()))
          ?{
          ??criteria.add(QueryUtils.getCriteriaParam(
          " address " ,?customer.getAddress()));
          ?}
          ?
          if ?( ! StringUtils.isEmpty(customer.getFax()))
          ?{
          ??criteria.add(QueryUtils.getCriteriaParam(
          " fax " ,?customer.getFax()));
          ?}?
          ?
          return ?criteriaPagedList(criteria,?startRow,?pageSize);
          }

          另外對應的一個count方法略去,只需要在前面加入一個
          criteria.setProjection(Projections.count("customerId"));

          因為考慮到以后的擴展,使用了一個Utils方法,QueryUtils.getCriteriaParam方法

          public ? static ? final ?SimpleExpression?getCriteriaParam(String?name,?String?param)
          {
          ?
          return ?Expression.like(name,? " % " ? + ?param? + ? " % " );
          }

          我們可以很容易的在 Backing Bean 上通過 Service 層拿到這個查詢結果的 List 和 Count 值,相關的getDatePage方法如下。
          如果你不了解這個 getDataPage 方法的含義,請仔細閱讀“在JSF中實現分頁(二)”一文,并仔細思考該方法的含義。

          protected ?DataPage?getDataPage( int ?startRow,? int ?pageSize)
          {
          ?List?queryCustomerList?
          = ?customerService.queryCustomer(customer,? this .startRow,? this .getPageSize());
          ?
          int ?dataSetSize? = ?customerService.countQueryCustomer(customer);
          ?
          return ? new ?DataPage(dataSetSize,?startRow,?queryCustomerList);
          }

          在同一個 Backing Bean 中,我們放了一個存放查詢條件的VO - Customer,并在頁面中使用<t:saveState>保存其狀態,使其查詢條件不會隨著翻頁而丟失。

          <t:saveState value="#{customerListBean.customer}"/>

          在頁面中,我們把所有的查詢條件都放到該 VO 中,在 getDataPage 方法中就會在適當的時候調用新的查詢條件來查詢新的數據,這一切都不需要我們動手的。

          在 Backing Bean 中有這樣的一個方法:

          public ?String?query()
          {
          ?dataModel.setWrappedData(getDataPage(
          0 ,?getPageSize()));
          ?
          return ? " success " ;
          }

          只是把數據清空,并強制 PagedListDataModel 讀取數據,然后我們返回相同的頁面,這個時候,系統按照用戶輸入的查詢條件拿到查詢結果以后,返回同一頁面,該頁面中的使用 LocalDataModel 的那個 DataTable 就會把結果顯示出來。

          請注意,這里 LocalDataModel 和 Customer 都在同一個 Backing Bean 中。

          是不是覺得很簡單呢,一切都歸功于 getDataPage 這個方法,我們幾乎不需要做什么額外的操作就可以達到我們的目的。

          因為該方法在一個商業項目中使用,代碼不便公布,只能把里面的一些代碼抽取出來,零零碎碎的拿給大家看,如果大家有什么疑問的話,可以在論壇上提出來,我會盡力解答的,另外這個方法也會在空閑的時候 Merge 到 MyPSP 項目中去。

          posted on 2006-03-28 19:12 steady 閱讀(6687) 評論(5)  編輯  收藏 所屬分類: JSF & Myfaces

          FeedBack:
          # re: 在JSF中實現分頁(三)  2006-03-28 20:34 fanse
          為什么要用這么復雜的呢,我們用過一個插件,
          http://jsptags.com/tags/navigation/pager/index.jsp
            回復  更多評論
            
          # re: 在JSF中實現分頁(三)  2006-03-28 20:37 steady
          完全不相關的留言,略去。  回復  更多評論
            
          # re: 在JSF中實現分頁(三)  2006-07-28 10:18 
          QQ 52018080 尋求幫助。沒看明白,然后 分頁插件 怎么用的 沒說清楚。
          這些方法的參數怎么用的,沒有注釋。  回復  更多評論
            
          # re: 在JSF中實現分頁(三)  2006-12-08 15:00 robert[匿名]
          一個user request要查詢3次數據庫, 6個sql操作
          效率太低了  回復  更多評論
            
          # re: 在JSF中實現分頁(三) [未登錄] 2008-01-09 16:04 小偉
          我的分頁也是參考了這種模式,現在我遇到的問題正是你第三章所說的,用戶執行一些操作后總是返回第一頁,我想返回同一頁,看你寫的不是很明白,我曾利用first這個屬性來搞,但還是不理想。
          我獲取分頁的方法是這個
          /**
          * 指定條件分頁
          * @param int startRow
          * @param int pageSize
          * return DataPage
          */
          protected DataPage getDataPage(int startRow, int pageSize) {
          String whereStr = getSelectWhereStrMsg();
          if(whereStr == null || whereStr.equals("")){
          dataPage = iabs.getAfficheListDataPage(startRow, pageSize, "");
          log.info("AfficheManager返回getDataPage(int startRow, int pageSize)");
          }
          else{
          dataPage =iabs.getAfficheListDataPage(startRow, pageSize, whereStr);
          log.info("AfficheManager返回getDataPage(int startRow, int pageSize,whereStr)");
          }
          return dataPage;
          }
            回復  更多評論
            
          主站蜘蛛池模板: 潞城市| 兴国县| 上杭县| 繁峙县| 垦利县| 清苑县| 潢川县| 大冶市| 太仓市| 阿尔山市| 孟州市| 海盐县| 东丰县| 大化| 越西县| 克什克腾旗| 彰武县| 布拖县| 滨海县| 巧家县| 慈溪市| 宜良县| 新巴尔虎左旗| 自贡市| 隆尧县| 湟源县| 襄汾县| 德清县| 长葛市| 长寿区| 洛隆县| 保山市| 临泽县| 阿合奇县| 万全县| 林芝县| 汉阴县| 巧家县| 武汉市| 泗阳县| 庄浪县|