在JSF中實現分頁(三)
zhuan(http://www.steadyxp.com/archives/189.html)
好久沒有寫點東西了,這次想把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 這個方法,我們幾乎不需要做什么額外的操作就可以達到我們的目的。
因為該方法在一個商業項目中使用,代碼不便公布,只能把里面的一些代碼抽取出來,零零碎碎的拿給大家看