分页有两种情况,一种是将数据一次全部读取,然后再内存中分页;另一种是每次只获取一页的内容。这两种情况都应当在系统中用到,但他们对应的情况不同。一次全部读取的适用于小数据量,比如一个订单下的全部订单明细;而分页查询的情况适用于顶层对象的不同查询条件下的列表,比如全部订单列表。
内存分页
由标准分页组件来实现,比如rich:datascroller,它的明显优点是和要分页的内容是分离的。
这种情况特别适用于hibernate、jpa等支持的实体的列表属性,比如一个订单的全部订单明细,当我们获取一个订单时,其实它的全部明细已经被获取(可能是延迟加载), 然后由分页组件来分页显示
<a:region>
<h:dataTable width="483" id="carList" rows="1" columnClasses="col"
value="#{dataTableScrollerBean.allCars}" var="category">
<f:facet name="header">
<rich:columnGroup>
<h:column>
<h:outputText styleClass="headerText" value="Make" />
</h:column>
</rich:columnGroup>
</f:facet>
<h:column>
<h:inputText value="#{category.make}" />
</h:column>
</h:dataTable>
<rich:spacer height="30" />
<rich:datascroller align="left" ajaxSingle="false" for="carList" ajaxSingle="false" maxPages="20" />
</a:region>
还有一种情形非常普遍,那就是分页且带编辑,就是说可以分页批量修改订单明细的内容,然后一起更新到数据库,这需要在内存中保存住该列表,最普通的做法是放入session中,而seam给出了一种更好的解决方案:对话,利用了session存放数据的功能,而又能及时清除session(不需要手工维护session)。当点击分页操作时,会将页面上列表中的输入框中的内容更新到对应的后台list中,最终保存时将整个list保存即可。
问题:当<rich:datascroller ajaxSingle="false"不为false时不会执行table中输入组件的解码,也就不会将页面的输入值更新到list中,在外面加上a:region表明这提交这个区域里的组件,这样外面的输入框就不会执行验证了。
查询分页
查询分页目前我还见过有支持的组件,这种分页需要处理两方面的任务,1)获取分页数据
2)页面显示分页控制
我目前知道的比较好的方法是seam提供的query框架,详见seam文档。
做点补从:
seam的query框架的后台部分已经是相当完善了,缺乏的是分页的页面展现,我们简单的将分页封装成一个组件,这样所有使用分页的页面都可以简单的引用了。
分页组件
文件名:/template/page.xhtml
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:s="http://jboss.com/products/seam/taglib"
xmlns:rich="http://richfaces.org/rich"
>
<ui:composition>
<h:commandLink view="#{linkurl}" rendered="#{searchbean.previousExists}" value="首页">
<f:param name="firstResult" value="0"/>
</h:commandLink>
 
<h:commandLink view="#{linkurl}" rendered="#{searchbean.previousExists}" value="上一页">
<f:param name="firstResult" value="#{searchbean.previousFirstResult}"/>
</h:commandLink>
 
<h:commandLink view="#{linkurl}" rendered="#{searchbean.nextExists}" value="下一页">
<f:param name="firstResult" value="#{searchbean.nextFirstResult}"/>
</h:commandLink>
 
<h:commandLink view="#{linkurl}" rendered="#{searchbean.nextExists}" value="未页">
<f:param name="firstResult" value="#{searchbean.lastFirstResult}"/>
</h:commandLink>
 
共#{searchbean.resultCount}条记录,共#{searchbean.pageCount}页,每页#{searchbean.maxResults}条,当前第
<h:outputText value="#{searchbean.firstResult/searchbean.maxResults+1}">
<f:convertNumber integerOnly="true"/>
</h:outputText>
页
</ui:composition>
</html>
使用分页组件
<h:dataTble>
..........
</h:dataTable>
<!--分页组件-->
<ui:include src="/template/page.xhtml">
<ui:param name="searchbean" value="#{jsys_search}"/><!--query ->
<ui:param name="linkurl" value="/transfer/transferBrowseList.xhtml"/><!--本页面-->
</ui:include>