Dev@Free

zJun's Tech Weblog

Displaytag1.1大数据量分页的例子

Displaytag1.1支持在外部实现大数据量分页。主要有两种方式实现:

Displaytag 1.1 offers two alternative ways for working with partial lists:

  • the first one uses the valuelist pattern, and requires that the object that you give to displaytag implements the org.displaytag.pagination.PaginatedList interface. You can pass this object to displaytag as an usual list, and it will extract paging and sorting information from it. This way is more recommended if you have to build your backend layer and you can easily follow this pattern.
  • a second way, recommended if you only have to use partial list for few tables that show a performance problem using full lists, is passing all the needed parameters as separate tag attributes (recors to be shown, page number, total number of records...)

其中第二种方式看起来较为简单,只需在<displaytag>中增加两个属性:partialList="true"size="resultSize"即可,但是在使用发现这种方式由于是在原来内存分页的基础上修改的,所以还是存在一些Bug(比如:分页导航的值不会变......)

所以这里介绍Displaytag推荐的第一种方式,即:
实现org.displaytag.pagination.PaginatedListorg.displaytag.pagination.PaginatedList接口。

实现PaginatedList接口:

import  java.util.List;

import
 org.displaytag.pagination.PaginatedList;
import
 org.displaytag.properties.SortOrderEnum;

/**
 * 分页列表
 * 
 * 
@author  John.Zhu
 * 
 
*/

public   class  PageList  implements  PaginatedList  {
    
/**
     * 每页的列表
     
*/

    
private  List list;

    
/**
     * 当前页码
     
*/

    
private   int  pageNumber  =   1 ;

    
/**
     * 每页记录数 page size
     
*/

    
private   int  objectsPerPage  =   15 ;

    
/**
     * 总记录数
     
*/

    
private   int  fullListSize  =   0 ;

    
private
 String sortCriterion;

    
private
 SortOrderEnum sortDirection;

    
private
 String searchId;

    
public  List getList() 
{
        
return
 list;
    }


    
public   void  setList(List list)  {
        
this .list  =
 list;
    }


    
public   int  getPageNumber()  {
        
return
 pageNumber;
    }


    
public   void  setPageNumber( int  pageNumber)  {
        
this .pageNumber  =
 pageNumber;
    }


    
public   int  getObjectsPerPage()  {
        
return
 objectsPerPage;
    }


    
public   void  setObjectsPerPage( int  objectsPerPage)  {
        
this .objectsPerPage  =
 objectsPerPage;
    }


    
public   int  getFullListSize()  {
        
return
 fullListSize;
    }


    
public   void  setFullListSize( int  fullListSize)  {
        
this .fullListSize  =
 fullListSize;
    }


    
public  String getSortCriterion()  {
        
return
 sortCriterion;
    }


    
public   void  setSortCriterion(String sortCriterion)  {
        
this .sortCriterion  =
 sortCriterion;
    }


    
public  SortOrderEnum getSortDirection()  {
        
return
 sortDirection;
    }


    
public   void  setSortDirection(SortOrderEnum sortDirection)  {
        
this .sortDirection  =
 sortDirection;
    }


    
public  String getSearchId()  {
        
return
 searchId;
    }


    
public   void  setSearchId(String searchId)  {
        
this .searchId  =
 searchId;
    }


}

Contoller:
/**
     * 分页查询
     * 
     * 
@param  request
     * 
@param
 response
     * 
@return

     * 
@throws  Exception
     
*/

    
private  ModelAndView paging(HttpServletRequest request,
            HttpServletResponse response, ModelAndView mav) 
throws  Exception 
{
        
//  获取当前页数,displaytag通过参数"page"传递这个值

                 int  pageNumber;
        
if  (request.getParameter( " page " !=   null

                
&&   ! "" .equals(request.getParameter( " page " )))  {
            pageNumber 
=  Integer.parseInt(request.getParameter( " page "
));
        }
  else   {
            pageNumber 
=   1
;
        }

        PageList pageList 
=   new  PageList();
        Map map 
=  WebUtils.getParametersStartingWith(request,  " search_ "
);
        Page page 
=
 dao.query(map, pageNumber, PAGE_SIZE);
                
//  设置当前页数

        pageList.setPageNumber(pageNumber);
                
//  设置当前页列表

        pageList.setList(page.getResults());
                
//  设置page size

        pageList.setObjectsPerPage(PAGE_SIZE);
                
//  设置总页数

        pageList.setFullListSize(page.getTotalCount());

        mav.addObject(
" results "
, pageList);

        
return
 mav;
    }

好了,现在直接在JSP上使用 displaytag就行了:
< display:table  name ="${results}"  id ="row"  class ="simple nocol"  pagesize ="${pageSize}"  export ="true"  
                    decorator
="org.displaytag.decorator.TotalTableDecorator"
 
                    requestURI
="${pageContext.request.contextPath}/pageQuery.do?method=paging" >

                 
< display:column  property ="date.time"  title ="日期"  format ="{0,date,yyyy-MM-dd}"  sortable ="false"   />
                
< display:column  property ="code"  title ="编码"  group ="1"  sortable ="false"   />
                
< display:column  property ="name"  title ="名称"  group ="1"  sortable ="false"   />
                 
< display:column  property ="costTotal"  title ="总额(元)"  format ="{0,number,0,000}"  total ="true"  sortable ="false"   />

</ display:table >

posted on 2007-02-08 11:35 zJun's帛罗阁 阅读(7424) 评论(20)  编辑  收藏 所属分类: 开发环境

评论

# re: Displaytag1.1大数据量分页的例子[未登录] 2007-04-03 01:46 jerry

requestURI ="${pageContext.request.contextPath}/pageQuery.do?method=paging"

你有没有碰到过当点下一页时会出现http://xxx/pageQuery.do?method=paging&method=paging  回复  更多评论   

# re: Displaytag1.1大数据量分页的例子 2007-09-30 16:11 fenix

楼主是个负责人的好人,顶顶  回复  更多评论   

# re: Displaytag1.1大数据量分页的例子 2007-09-30 16:27 fenix

有个问题,楼主。你的PAGE对象是什么样的哦  回复  更多评论   

# re: Displaytag1.1大数据量分页的例子 2007-12-28 15:23 迷途羔羊

可是点击页面排序的时候不排序了啊  回复  更多评论   

# re: Displaytag1.1大数据量分页的例子[未登录] 2008-02-29 18:38 佳佳

楼主,你的ModelAndView 是什么样的呢,能不能提供更完整的例子呢  回复  更多评论   

# re: Displaytag1.1大数据量分页的例子 2008-02-29 20:22 zJun's帛罗阁

@迷途羔羊
排序是要自己写代码实现的,所以叫 external paging嘛。  回复  更多评论   

# re: Displaytag1.1大数据量分页的例子 2008-02-29 20:31 zJun's帛罗阁

@佳佳
这个ModelAndView是Spring中的类,具体可以参考这里: http://static.springframework.org/spring/docs/2.0.x/api/org/springframework/web/servlet/ModelAndView.html
也可以换成是Struts的实现,这只是用在page和controller之间传递参数用的,和用request是一样的。  回复  更多评论   

# re: Displaytag1.1大数据量分页的例子 2008-03-13 19:18 yushibo

Page对象是什么,没写出来  回复  更多评论   

# re: Displaytag1.1大数据量分页的例子 2008-03-13 19:32 zJun's帛罗阁

@yushibo

public class Page {

static private int DEFAULT_PAGE_SIZE = 15;

/**
* 每页的记录数
*/
private int pageSize = DEFAULT_PAGE_SIZE;

/**
* 当前页第一条数据在List中的位置,从0开始
*/
private int start;

/**
* 当前页中存放的记录
*/
private List results;

/**
* 总记录数
*/
private int totalCount;

/**
* 构造方法,只构造空页
*/
public Page() {
this(0, 0, DEFAULT_PAGE_SIZE, new ArrayList());
}

/**
* 默认构造方法
*
* @param start
* 本页数据在数据库中的起始位置
* @param totalSize
* 数据库中总记录条数
* @param pageSize
* 本页容量
* @param results
* 本页包含的数据
*/
public Page(int start, int totalSize, int pageSize, List results) {
this.pageSize = pageSize;
this.start = start;
this.totalCount = totalSize;
this.results = results;
}

/**
* 取数据库中包含的总记录数
*/
public int getTotalCount() {
return this.totalCount;
}

/**
* 取总页数
*/
public int getTotalPageCount() {
if (totalCount % pageSize == 0)
return totalCount / pageSize;
else
return totalCount / pageSize + 1;
}

/**
* 取每页数据容量
*/
public int getPageSize() {
return pageSize;
}

/**
* 当前页记录
*/
public List getResults() {
return results;
}

/**
* 取当前页码,页码从1开始
*/
public int getCurrentPageNo() {
return start / pageSize + 1;
}

/**
* 是否有下一页
*/
public boolean hasNextPage() {
return this.getCurrentPageNo() < this.getTotalPageCount() - 1;
}

/**
* 是否有上一页
*/
public boolean hasPreviousPage() {
return this.getCurrentPageNo() > 1;
}

/**
* 获取任一页第一条数据的位置,每页条数使用默认值
*/
protected static int getStartOfPage(int pageNo) {
return getStartOfPage(pageNo, DEFAULT_PAGE_SIZE);
}

/**
* 获取任一页第一条数据的位置,startIndex从0开始
*/
public static int getStartOfPage(int pageNo, int pageSize) {
return (pageNo - 1) * pageSize;
}

/**
* 设置总记录数
*/
public void setTotalCount(int totalCount) {
this.totalCount = totalCount;
}

/**
* 设置记录
* @param results
*/
public void setResults(List results) {
this.results = results;
}

public void setPageSize(int pageSize) {
this.pageSize = pageSize;
}
}
  回复  更多评论   

# re: DAO的实现能否提供源代码。 2008-04-26 14:19 xieamao

代码中dao,怎么没有生成实例就直接引用方法。难道是静态方法。但是貌似不是类,而是一个变量,因为小写。
dao.query(*)能否提供,DAO的实现。  回复  更多评论   

# re: Displaytag1.1大数据量分页的例子 2008-04-27 23:46 zJun's帛罗阁

@xieamao
dao.query()中是使用Hibernate实现分页的查询,在有很多现成的实现。  回复  更多评论   

# re: Displaytag1.1大数据量分页的例子 2008-04-28 20:20 xieamao

@zJun's帛罗阁
@xieamao
dao.query()中是使用Hibernate实现分页的查询,在有很多现成的实现。但函数中的参数MAP起什么作用,我觉得PageNumber,Page_Size就够了。所以我想问一下您的代码实现。  回复  更多评论   

# re: Displaytag1.1大数据量分页的例子 2008-04-29 10:45 xieamao

ao.query()中是使用Hibernate实现分页的查询,但函数中的参数MAP起什么作用,我觉得PageNumber,Page_Size就够了。所以我想问一下您的代码实现(能贴出来么,或者把关键代码贴出来)  回复  更多评论   

# re: Displaytag1.1大数据量分页的例子 2008-04-29 11:20 xieamao

dao.query()中的map,是不是设置Page对象属性值 ,感觉这个Page对象不要也可以。  回复  更多评论   

# re: Displaytag1.1大数据量分页的例子 2008-04-29 11:24 xieamao

问的问题有点初级,自己动手实现一下。  回复  更多评论   

# re: Displaytag1.1大数据量分页的例子 2008-04-30 14:24 xieamao

Controller 中的PAGE_SIZE和dao变量是怎么来的,能否贴出代码。  回复  更多评论   

# re: Displaytag1.1大数据量分页的例子 2008-05-04 14:07 xieamao

俺扩展成功了!
但是感觉每翻一次页就查询一次数据库,这样大数据量显示时,虽然不会出现内存占用过大的问题,但是查询过于频繁。能不能这样,一次查询500,每页显示20条,这200条之后,点击下一页时,再继续查询500条记录(如果没有500条就查剩余的)这样可以有效缓解,数据库负载。
但我想来想去不知如何实现。按照此文所提供的方法。
  回复  更多评论   

# re: Displaytag1.1大数据量分页的例子 2008-05-04 14:14 xieamao

应该为这500条之后  回复  更多评论   

# re: Displaytag1.1大数据量分页的例子[未登录] 2008-05-15 01:50 lg

有个问题要请教下,
在dt中,table本身是支持一个sort="page"或者"list"来表示排序是在整个list中还是在一个页面中进行的!

现在的问题是,自己实现列表的排序,dt会有一个自动生成的sort="*待排序的列*",,所以在action(struts)中,怎样得到sort="page"或者“list”这个sort呢?另外,我发现在 PaginatedList中没有表示这个sort的变量呢?

lz有办法没?

--------------
另外,
一般按客户的要求,都可以通过一定的条件过滤在列表中显示的数据。而我发现,dt好像没有办法实现这样的功能!
即,输入一个过滤条件,列表中显示的数据是被过滤的项?
望lz指教!  回复  更多评论   

# re: Displaytag1.1大数据量分页的例子[未登录] 2008-06-06 13:15 zz

晕 效果出来了 ,可是下边不知道 为什么多了一行 空行 ,郁闷啊!: (  回复  更多评论   


只有注册用户登录后才能发表评论。


网站导航:
 

导航

<2008年3月>
2425262728291
2345678
9101112131415
16171819202122
23242526272829
303112345

统计

常用链接

留言簿(15)

随笔分类

随笔档案

相册

收藏夹

博客

文档

站点

论坛

搜索

积分与排名

最新评论

阅读排行榜

评论排行榜