📄 在jsf中实现分页 jsf- 实现 java● 咖啡馆 -- jsf中文论坛.htm
字号:
{
// even when no row is selected, we still need a page
// object so that we know the amount of data available.
startRow = 0;
}
// invoke method on enclosing class
page = fetchPage(startRow, pageSize);
return page;
}
/** *//**
* Return the object corresponding to the current rowIndex. If the DataPage
* object currently cached doesn't include that index then fetchPage is
* called to retrieve the appropriate page.
*/
public Object getRowData()
{
if (rowIndex < 0)
{
throw new IllegalArgumentException(
"Invalid rowIndex for PagedListDataModel; not within page");
}
// ensure page exists; if rowIndex is beyond dataset size, then
// we should still get back a DataPage object with the dataset size
// in it
if (page == null)
{
page = fetchPage(rowIndex, pageSize);
}
int datasetSize = page.getDatasetSize();
int startRow = page.getStartRow();
int nRows = page.getData().size();
int endRow = startRow + nRows;
if (rowIndex >= datasetSize)
{
throw new IllegalArgumentException("Invalid rowIndex");
}
if (rowIndex < startRow)
{
page = fetchPage(rowIndex, pageSize);
startRow = page.getStartRow();
}
else if (rowIndex >= endRow)
{
page = fetchPage(rowIndex, pageSize);
startRow = page.getStartRow();
}
return page.getData().get(rowIndex - startRow);
}
public Object getWrappedData()
{
return page.getData();
}
/** *//**
* Return true if the rowIndex value is currently set to a value that
* matches some element in the dataset. Note that it may match a row that is
* not in the currently cached DataPage; if so then when getRowData is
* called the required DataPage will be fetched by calling fetchData.
*/
public boolean isRowAvailable()
{
DataPage page = getPage();
if (page == null)
{
return false;
}
int rowIndex = getRowIndex();
if (rowIndex < 0)
{
return false;
}
else if (rowIndex >= page.getDatasetSize())
{
return false;
}
else
{
return true;
}
}
/** *//**
* Method which must be implemented in cooperation with the managed bean
* class to fetch data on demand.
*/
public abstract DataPage fetchPage(int startRow, int pageSize);
}
</TEXTAREA><BR><BR> 最后,我们需要在Backing
Bean中加一些东西,调用业务逻辑,并将数据交给PagedListDataModel,来帮我们完成最后的<B
style="COLOR: red; BACKGROUND-COLOR: #ffff66">分页</B></FONT>工作。<BR><BR><FONT
color=red>以下是代码:</FONT><BR><TEXTAREA class=java name=code rows=15 cols=100> public SomeManagedBean {
.
private DataPage getDataPage(int startRow, int pageSize) {
// access database here, or call EJB to do so
}
public DataModel getDataModel() {
if (dataModel == null) {
dataModel = new LocalDataModel(getRowsPerPage());
}
return dataModel;
}
private class LocalDataModel extends PagedListDataModel {
public LocalDataModel(int pageSize) {
super(pageSize);
}
public DataPage fetchPage(int startRow, int pageSize) {
// call enclosing managed bean method to fetch the data
return getDataPage(startRow, pageSize);
}
}
</TEXTAREA><BR><BR>这里面有一个getDataPage的方法,只需要把所有业务逻辑的调用放在这里就可以了,最后业务逻辑调用的结果返回一个List,总条数返回一个int型的count放到DataPage中去就可以了。<BR><BR><BR><BR>
为了实现复用,把上面第三段的代码中的LocalDataModel类和getDataPage方法抽到BasePagedBackingBean中,把getDataPage方法改成:<BR><BR><BR><BR>
protected abstract DataPage getDataPage(int startRow, int
pageSize);<BR><BR><BR><BR> 这样我们把所有需要<B
style="COLOR: red; BACKGROUND-COLOR: #ffff66">分页</B></FONT>的Backing
Bean继承自这个抽象类,并实现getDataPage方法即可很容易的实现<B
style="COLOR: red; BACKGROUND-COLOR: #ffff66">分页</B></FONT>。<BR><BR><BR><BR>
在具体应用中可以这么写:<BR><BR><BR><BR><FONT color=red>以下是代码:</FONT><BR><TEXTAREA class=java name=code rows=15 cols=100> protected DataPage getDataPage(int startRow, int pageSize)
{
List scheduleList = scheduleService.getSchedulesByDate(scheduleDate, startRow, pageSize);
int dataSetSize = scheduleService.getSchedulesCountByDate(scheduleDate);
return new DataPage(dataSetSize, startRow, scheduleList);
}
</TEXTAREA><BR><BR>在数据访问中,我们只需要取出我们需要行数的记录就可以了,这在hibernate中非常容易实现。<BR><BR>
如果使用Criteria查询的话,只要加上:<BR><BR>
criteria.setFirstResult(startRow);<BR><BR>
criteria.setMaxResults(pageSize);<BR><BR>
使用Query查询的话,只要加上<BR><BR>
query.setFirstResult(startRow);<BR><BR>
query.setMaxResults(pageSize);<BR><BR>
并把两个参数传入即可。<BR><BR>
我们还需要另外写一个Count的DAO,取出相同查询条件的记录条数即可。<BR><BR>
还要修改一下Backing
Bean中与dataTable绑定的property,将返回类型由List改成DataModel,而第一篇中用到的页面不需要做任何修改就可以满足新的需求了。<BR><BR>
里面最重要的是 PagedListDataModel 中 fetchPage
这个方法,当满足取数据的条件时,都会调用它取数据,因为业务逻辑不同,不便于将业务逻辑的调用放在里面实现,于是将其作为抽象方法,将具体的实现放到具体的Backing
Bean中进行,在BaseBackingBean中,实现了这个方法,调用了getDataPage(startRow,
pageSize)这个方法,而在BaseBackingBean中,这个方法又推迟到更具体的页面中实现,这样,我们在具体的页面中只需要实现一个getDataPage(startRow,
pageSize)这个方法访问业务逻辑。<BR><BR>
大功告成,这个实现把前面遇到的两个问题都解决了,On-demand
loading是没有问题了,因为只有在首次读取和换页的时候DataModel才会向数据库请求数据,虽然在JSF的生命周期中多次调用与dataTable绑定的方法,但是因为每次业务逻辑请求以后,数据都会存放在DataPage中,如果里面的数据满足需求的话,就不再请求访问数据库,这样多次访问数据库的问题也解决了。<BR><BR>
虽然这样的话,dataScrollor的Tag使用起来还是很复杂,通常在同一个项目中,我们只会使用一种样式的<B
style="COLOR: red; BACKGROUND-COLOR: #ffff66">分页</B></FONT>导航,不过没关系,我们只需要修改以下DataScrollor的Render
Kit,把一些可以定义的值固定下来,再定义一个TLD文件,就可以在项目中使用简化版的Tag了。<BR><BR>
这个方法一开始发布在Myfaces的Wiki中,<A
href="http://wiki.apache.org/myfaces/WorkingWithLargeTables"
target=_blank>http://wiki.apache.org/myfaces/WorkingWithLargeTables</A>,那里很少有人关注到,大家有兴趣可以看看原文,本文只是对这种方法做一些简单的介绍,并非自创,希望大家能够多多关注开源社区,因为那里有最新最好的东西。<BR><BR>
从Nightly
Build服务器中拿到的12.27的Myfaces包,发现里面扩充了很多新的Component,只是并没有正式发布,大家有兴趣的话可以研究研究。<BR><BR><BR><BR><BR><BR></SPAN></TD></TR>
<FORM method=post>
<TR vAlign=bottom bgColor=#f7f7f7>
<TD colSpan=5><BR><!----><IMG
src="在JSF中实现分页 JSF- 实现 Java● 咖啡馆 -- JSF中文论坛.files/sigline.gif"
border=0> <BR>程序<BR><!----><FONT color=red>[1楼]</FONT> |
IP:已记录| <SPAN class=bold>Posted:</SPAN>2006-09-8 11:10 AM|</TD>
<TD vAlign=bottom align=right><A
href="javascript:scroll(0,0)"><IMG alt=回到顶端
src="在JSF中实现分页 JSF- 实现 Java● 咖啡馆 -- JSF中文论坛.files/top.gif"
border=0></A></TD></TR></FORM></TBODY></TABLE></TD></TR></TBODY></TABLE>
<TABLE width="100%" align=center>
<TBODY>
<TR>
<TD height=1></TD></TR></TBODY></TABLE><!--<!--帖子模版-->
<TABLE style="TABLE-LAYOUT: fixed; WORD-WRAP: break-word" cellSpacing=1
cellPadding=0 width="100%" align=center bgColor=#e5e3e3>
<TBODY>
<TR>
<TD
style="PADDING-RIGHT: 5px; PADDING-LEFT: 5px; PADDING-BOTTOM: 5px; PADDING-TOP: 5px"
vAlign=top width="20%" bgColor=#ffffff height="100%"><FONT
face=Gulim color=#000066><SPAN class=bold>icess</SPAN></FONT>
<TABLE style="TABLE-LAYOUT: fixed" cellSpacing=0 cellPadding=0
width="95%" border=0>
<TBODY>
<TR>
<TD align=middle><BR><IMG
src="在JSF中实现分页 JSF- 实现 Java● 咖啡馆 -- JSF中文论坛.files/0.gif"
border=0></TD></TR></TBODY></TABLE><BR><IMG
src="在JSF中实现分页 JSF- 实现 Java● 咖啡馆 -- JSF中文论坛.files/10super.gif"><BR>级别:
<FONT color=#555555>论坛管理员<IMG alt=该用户目前不在线
src="在JSF中实现分页 JSF- 实现 Java● 咖啡馆 -- JSF中文论坛.files/offonline.gif"></FONT><BR>发贴:
<FONT color=green><SPAN class=bold>618</SPAN></FONT> (精华:<FONT
color=green><SPAN class=bold>0</SPAN></FONT>)<BR>威望: <FONT
color=#984b98><SPAN class=bold>268</SPAN></FONT><BR>咖啡豆: <FONT
color=red><SPAN
class=bold>2054</SPAN></FONT><BR>注册时间:2006-06-01<BR>最后登陆:2007-03-24
</TD>
<TD vAlign=top width="80%" bgColor=#ffffff height="100%">
<TABLE style="TABLE-LAYOUT: fixed; WORD-WRAP: break-word"
height="100%" cellSpacing=0 cellPadding=4 width="99%"
align=center><TBODY>
<TR>
<TD vAlign=top width="91%" bgColor=#ffffff colSpan=5><A
href="http://www.hexiao.cn/jsf/profile.php?action=show&username=icess"><IMG
alt=查看作者资料
src="在JSF中实现分页 JSF- 实现 Java● 咖啡馆 -- JSF中文论坛.files/profile.gif"
align=absMiddle border=0></A> <A
href="http://www.hexiao.cn/jsf/message.php?action=write&msgid=icess"><IMG
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -