02
2008
09

在JSF中实现分页(三)

好久没有写点东西了,这次想把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 这个方法,我们几乎不需要做什么额外的操作就可以达到我们的目的。

因为该方法在一个商业项目中使用,代码不便公布,只能把里面的一些代码抽取出来,零零碎碎的拿给大家看


« 上一篇 下一篇 »

评论列表:

1.  2011-07-30 11:30:27 回复该评论
你好,请问你的分页数据是放在request 还是session里面
我这边在request里面一直无法实现分页,点击页码时JSF会在生命周期的恢复视图阶段把数值清空,session是没有问题的。

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。