好久沒有寫點東西了,這次想把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 閱讀(6684)
評論(5) 編輯 收藏 所屬分類:
JSF & Myfaces