论坛首页 Java企业应用论坛

DisplayTag分页机制

浏览 8885 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2005-10-13  
在DisplayTag中对分页的处理如下:
(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中的代码进行修改,现在我们也是在应急做一些这样的修改,但总觉得不是什么好办法,还请大家多多讨论。
   发表时间:2005-10-14  
displaytag 的可定制性很强,但是似乎留给开发者编程的接口似乎是少了些,这点上  valuelist好像要好一点,兔八哥好像使用 hibernate和displaytag实现了只取当前页面数据的方法,不知道是不是封装了一下. 可以考虑一下 valuelist.
0 请登录后投票
   发表时间:2006-01-05  
valuelist的更新太慢了。
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics