浏览 8885 次
锁定老帖子 主题:DisplayTag分页机制
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2005-10-13
(1) org.displaytag.tags.TableTag: 这个类是<table>标签的处理类,它处理<table>标签中的参数信息,在其中有一个参数pagesize,在标签处理过程中,会根据此参数判断是否需要分页。 public int doEndTag(); throws JspException { ... ... //代码省略 setupViewableData();; ... ... //代码省略 //以下的代码是将原来列表中的数据,转化为 [Row] 对 象,然 后 保 存 在 新 的 列 表 中,所有的行信息都保存在 [tableModel] 对 象 中。 while (this.tableIterator.hasNext();); { Object iteratedObject = this.tableIterator.next();; this.rowNumber++; // Row object for Cell values this.currentRow = new Row(iteratedObject, this.rowNumber);; this.tableModel.addRow(this.currentRow);; } ... ... //代码省略 writeHTMLData();; //生成表格的HTML ... ... //代码省略 } //此 方 法 是 准 备 需 要 显 示 的 数 据 protected void setupViewableData(); { ... ... //代码省略 if (this.pagesize > 0); { //生成一个分页 需 要 的 处 理 对 象 this.listHelper = new SmartListHelper(fullList, fullList.size();, this.pagesize, this.properties);; this.listHelper.setCurrentPage(this.pageNumber);; pageOffset = this.listHelper.getFirstIndexForCurrentPage();; fullList = this.listHelper.getListForCurrentPage();; } this.tableModel.setRowListPage(fullList);; this.tableModel.setPageOffset(pageOffset);; } private void writeHTMLData(); throws JspException { ... ... //代码省略 writeTableBody();; //生成表格体 ... ... //代码省略 } private void writeTableBody(); throws ObjectLookupException, DecoratorException { ... ... //代码省略 //从 [tableModel] 中 依 次处理每一行的数据 RowIterator rowIterator = this.tableModel.getRowIterator(false);; ... ... //代码省略 } (2) org.displaytag.pagination.SmartListHelper: 分页处理的辅助类,能过此类可以得到本页中的数据,并且可以生成页码导航的信息。其中有几个主要的属性: i) fullList: 保存所有数据的列表,由于DisplayTag的分页是在标签处理时进行的,所以在此传入的是数据完整的列表。 ii) pageSize: 每页的记录数,根据上面的代码,它等于<table>标签的pageSize属性的值。 iii) pageCount: 总的页数 iv) fullListSize: 总的记录数,如果fullList不为空的话,它的值就是fullList的size()。 在TableTag.setupViewableData方法中会调用getListForCurrentPage方法,取得当前页的数据,此方法的代码为: protected List getListForPage(int pageNumber); { log.debug("getListForPage page=" + pageNumber);; List list = new ArrayList(this.pageSize + 1);; int firstIndex = getFirstIndexForPage(pageNumber);; int lastIndex = getLastIndexForPage(pageNumber);; Iterator iterator = this.fullList.iterator();; int j = 0; while (iterator.hasNext();); { Object object = iterator.next();; if (j > lastIndex); { break; } else if (j >= firstIndex); { list.add(object);; } j++; } return list; }以上是V1.0以前的实现,在以前的版本中,采用一个最笨的逐个拷贝的方法,在最新的1.0版本中,实现优化为: protected List getListForPage(int pageNumber); { if (log.isDebugEnabled();); { log.debug(Messages.getString("SmartListHelper.debug.sublist", //$NON-NLS-1$ new Object[]{new Integer(pageNumber);}););; } int firstIndex = getFirstIndexForPage(pageNumber);; int lastIndex = getLastIndexForPage(pageNumber);; return this.fullList.subList(firstIndex, lastIndex + 1);; } 通过以上两个类的协调,DisplayTag就完成了分页的操作,这种机制的问题在于: (1) 最重要的缺点是在分页前必须将所有的数据传入,这样如果对10000条记录分页,先要 将所有10000条记录保存在一个列表中,传给DisplayTag才可以实现分页,效率极差。 对于实际的项目基本上不适用。 (2) 由于在分页时只能处理List,而且在代码中多处都写定了使用的是ArrayList,所以可扩展性基本没有,想自己在外围做一些对分页的处理很困难。 基于上面的分析,在实际中,可以做一个分页操作的接口,其中定义以下几项内容: [list] 总页数 总记录数 当前页码 每页记录数 当前页的数据列表[/list:u] 通过扩展接口,配合数据库操作的分页处理,可以在传给DisplayTag的列表中只保存当前页的数据,这样在DisplayTag中对分页的判断就依赖于外部已经分好页的数据了,就不需要再内部进行分页了。 当然这样需要对DisplayTag中的代码进行修改,现在我们也是在应急做一些这样的修改,但总觉得不是什么好办法,还请大家多多讨论。 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2005-10-14
displaytag 的可定制性很强,但是似乎留给开发者编程的接口似乎是少了些,这点上 valuelist好像要好一点,兔八哥好像使用 hibernate和displaytag实现了只取当前页面数据的方法,不知道是不是封装了一下. 可以考虑一下 valuelist.
|
|
返回顶楼 | |
发表时间:2006-01-05
valuelist的更新太慢了。
|
|
返回顶楼 | |