`

使用Display标签对大量数据使用外部排序实例(一)

阅读更多
  Display标签是个十分优秀的以表格形式显示数据的轻便标签,支持分页、排序及数据导出功能。经过在项目中实践检查,确实不错。

  针对大数据量的情况,如数据库里的大量记录,全部从数据库里取出,然后在内存中进行排序,效率不高,内存占用大。为此,标签十分体贴的提供了外部排序分页的功能(External Paging and Sorting)。关于外部排序、分页的概念及具体细节,请参见我的一篇翻译文章《Display标签外部排序与分页(External Paging and Sorting)》,是官方文档的翻译。

  官方文档中,没有介绍如何实现外部排序分页的细节,说它很容易实现。我结合我的应用环境(jdk 1.5、Oracle92i、tomcat5.5)试验了一下,果然很容易,实现标签要求的接口----PaginatedList,写一句分页的SQL(使用ROWNUM,大家都知道吧),将数据取出来交给标签来显示就可以了。

  为了让朋友更容易,我把代码贴出来。由于这个类与数据库操作类有些藕合,所以这个代码并不能运行,相关函数我进行了适当的注释,仅能用来演示实现思路。

  代码显得很多,有些代码是方便jsp页面上参数传递而进行的不是很必要的函数重载。
package com.wallimn.gyz.util;
import java.sql.Connection;
import java.util.List;
import java.util.Map;
import org.displaytag.pagination.PaginatedList;
import org.displaytag.properties.SortOrderEnum;
import com.wallimn.gyz.dao.BaseDao;
import com.wallimn.gyz.dao.DbManager;
public class OraPaginatedList implements PaginatedList {
	/**
	 * wrapped list
	 */
	private List> pagedList = null;
	/**
	 * Number of objects per page.
	 */
	private int objectsPerPage;
	/**
	 * Current page (starting from 1)
	 */
	private int currentPage;
	private String selectSql;
	private int fullSize;
	private String sortCriterion = null;
	private SortOrderEnum sortDirection = SortOrderEnum.DESCENDING;
	public OraPaginatedList(String sql) {
		selectSql = sql;
		this.objectsPerPage = 20;
		this.currentPage = 1;
	}
	public OraPaginatedList(String sql, int currentPage) {
		this.objectsPerPage = 20;
		this.currentPage = currentPage;
		selectSql = sql;
	}
	/**
	 * 设置当前面,内含null值判断代码,可以简化页面上的操作。
	 * 
	 * 作者:wallimn 时间:2009-1-22 下午12:07:31
	 * 邮件:wallimn@sohu.com
	 * 博客:http://blog.csdn.net/wallimn
	 * 参数:
	 * @param curPage
	 */
	public void setCurrentPage(String curPage){
		if(curPage==null || "null".equals(curPage))this.currentPage=1;
		else this.currentPage = Integer.parseInt(curPage);
	}
	public void setObjectsPerPage(int objectsPerPage){
		this.objectsPerPage = objectsPerPage;
	}
	public void setObjectsPerPage(String objectsPerPage){
		if(objectsPerPage==null || "null".equals(objectsPerPage))this.objectsPerPage=20;
		else this.objectsPerPage = Integer.parseInt(objectsPerPage);
	}
	@SuppressWarnings("unchecked")
	public List getList() {
		BaseDao dao = new BaseDao();
		// int startOffset = objectsPerPage * (currentPage - 1);
		String fullSql=null;
		if(this.sortCriterion!=null)fullSql=selectSql+ " order by "+this.sortCriterion+ " " + getSortDirectionStr();
		else fullSql =selectSql;
		//生成分页的SQL,使用ROWNUM
		String pageSql = dao.getPageSql(fullSql, (currentPage - 1)
				* objectsPerPage, (currentPage) * objectsPerPage);
		//System.out.println(pageSql);
		//使用正则表达式,变换成select count(*)的形式。
		String countSql = dao.getCountSql(selectSql);
		DbManager manager = DbManager.getInstance();
		Connection conn = manager.getConnection();
		pagedList = dao.dbSearch(conn, pageSql);
		fullSize = dao.getCount(conn, countSql);
		manager.closeConnection(conn);
		return pagedList;
	}
	public int getPageNumber() {
		return currentPage;
	}
	public int getObjectsPerPage() {
		return objectsPerPage;
	}
	public int getFullListSize() {
		return fullSize;
	}
	public void setSortCriterion(String fieldN) {
		this.sortCriterion = (fieldN == null || "null".equals(fieldN)) ? "1"
				: fieldN;
	}
	public String getSortCriterion() {
		return this.sortCriterion;
	}
	public void setSortDirection(String dir) {
		if (dir == null || "null".equals(dir) || "desc".equalsIgnoreCase(dir))
			sortDirection = SortOrderEnum.DESCENDING;
		else
			sortDirection = SortOrderEnum.ASCENDING;
	}
	public String getSortDirectionStr(){
		if(sortDirection == SortOrderEnum.ASCENDING)return "ASC";
		else return "DESC";
	}
	public SortOrderEnum getSortDirection() {
		return sortDirection;
	}
	public String getSearchId() {
		return Integer.toHexString(objectsPerPage * 10000 + currentPage);
	}
}


/***********本人原创,欢迎转载,转载请保留本人信息*************/
作者:wallimn 电邮:wallimn@sohu.com 时间:2009-02-09
博客:http://blog.csdn.net/wallimn http://wallimn.iteye.com
网络硬盘:http://wallimn.ys168.com
/***********文章发表请与本人联系,作者保留所有权利*************/
分享到:
评论
8 楼 wallimn 2011-01-05  
可以用可以不用,跟那个没有多少关系。
7 楼 lingmincc 2011-01-04  
你是否有用到属性decorator???
6 楼 wallimn 2011-01-04  
我也是直接写的,没有什么特殊的讲究呀。PaginatedList的实例有个getList()方法就可以了呀。
5 楼 lingmincc 2011-01-04  
我有个疑问,当我将PaginatedList这个实例传到JSP页面显示,我需要显示的内容是PaginatedList这个实例里的List对象中的属性,如List<App>,我需要显示的是app.appid,app.name这些类型,我发现直接写<display:column property="appid" title="appid"/>是会报找不到属性的???能解释下不,我看网上例子都是直接写属性的
4 楼 wallimn 2010-08-26  
如果参数不多,可以不用form,display标签会自动加到链接上,通过链接传递参数,参数多了会丢失。所以参数多了就要用form,在display标签的属性中有个属性,设置了之后,display标签会替你生成相应的js及html代码。
3 楼 wang_godsun 2010-08-26  
你的回复还挺快的。看了官方的文档和你的翻译,明白了你用的是第一种实现方式。但我还是没弄的太明白,display生产的页面代码里没有form,查询条件需要我自己建一个form吗,还是display直接传到action里呢了。我用的是truts2.
2 楼 wallimn 2010-08-25  
我在SQL里计算了这个值。
String pageSql = dao.getPageSql(fullSql, (currentPage - 1) 
                * objectsPerPage, (currentPage) * objectsPerPage);
1 楼 wang_godsun 2010-08-25  
你这个例子怎么这么简单,为什么没有官方文档里的(Integer.parseInt(request.getParameter((new ParamEncoder(tableId).encodeParameterName(TableTagParameters.PARAMETER_PAGE)))) - 1) * pageSize  这句呢?

相关推荐

Global site tag (gtag.js) - Google Analytics