Leo's Blog

  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  13 随笔 :: 3 文章 :: 18 评论 :: 0 Trackbacks



为 我们的项目写的一个轻量的分页API。目的在于将分页与数据查询的逻辑完全剥离。我以前看过robbin发的通过detachedCriteria实现的 分页那片贴子,里面把分页和数据查询结合在一起了。而我觉得分开更轻量,而且替换也比较容易。但是这个实现中有一个反模式,在逻辑中生成了代码,无奈之 选,为了简便。其中字符生成可以自己扩展i18n实现,应该非常容易。
分页实现的接口:
package com.goldnet.framework.util.paging;

/**
 * 分页操作的接口
 * 
@author Tin
 
*/

public interface IPagination {

    
/**
     * 默认的分页大小
     
*/

    
public static final int DEFAULT_PAGE_SIZE = 15;

    
/**
     * 默认的分页参数,指URL中用到的参数名
     
*/

    
public static final String PAGE_SIZE_KEY = "pageSize";

    
/**
     * 默认的页码参数,指URL中用到的参数名
     
*/

    
public static final String PAGE_NO_KEY = "pageno";

    
/**
     * 获取总页数
     * 
@return 总页数
     
*/

    
int getPageSum();

    
/**
     * 下一页的页码
     * 
@return
     
*/

    
int getNextPageNo();

    
/**
     * 上一页的页码
     * 
@return
     
*/

    
int getPrevPageNo();

    
/**
     * 是否有下一页,即是否为最后一页
     * 
@return 是否有下一页
     
*/

    
boolean hasNextPage();

    
/**
     * 是否有上一页,即是否为第一页
     * 
@return 是否有上一页
     
*/

    
boolean hasPrevPage();

    
/**
     * 添加参数名称、值对,如果页面需要使用parameters传递分页外的附加参数
     * 
@param parameterName 参数名
     * 
@param parameterValue 参数值
     
*/

    
void addPageParameter(String parameterName, String parameterValue);

    String getPageUrl();

    String getPageHtmlStr();

    
int getItemSum();

    
void setItemSum(int itemSum);

    String getPageExtension();

    
void setPageExtension(String pageExtension);

    String getPageName();

    
void setPageName(String pageName);

    
int getPageNo();

    
void setPageNo(int pageNo);

    
int getPageSize();

    
void setPageSize(int pageSize);

}

抽象基类:
/**
 *
 
*/

package com.goldnet.framework.util.paging;

import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;


/**
 * 对PagingString的重构
 * 
@author Tin
 *
 
*/

public abstract class AbstractPagination implements IPagination {
    
/**
     * Page上显示的List中的domainModel的总数
     
*/

    
protected int itemSum = -1;

    
/**
     * 分页的大小
     
*/

    
protected int pageSize = DEFAULT_PAGE_SIZE;

    
/**
     * 页数
     
*/

    
protected int pageNo = 0;

    
/**
     * 分页的页面的相对URL,不包括后缀
     
*/

    
protected String pageName = null;

    
/**
     * 页面的URL的后缀
     
*/

    
protected String pageExtension = ".action";

    
/**
     * 参数列表
     
*/

    
protected List<PageParameter> parameterList = new LinkedList<PageParameter>();

    
/**
         * 返回的分页信息的字符串
         
*/

    
protected String pageHtmlStr = null;

    
/**
     * 默认的构造函数
     * 
@param pageName 分页的页面的相对URL,不包括后缀
     * 
@param pageExtension 页面的URL的后缀
     * 
@param itemSum Page上显示的List中的domainModel的总数
     * 
@param pageNo 页数
     * 
@param pageSize 分页的大小
     
*/

    
public AbstractPagination(String pageName, String pageExtension,
        
int itemSum, int pageNo, int pageSize) {
        
super();

        
this.pageName = pageName;
        
this.pageExtension = pageExtension;
        
this.itemSum = itemSum;
        
this.pageNo = pageNo;
        
this.pageSize = pageSize;
    }


    
/**
     * 无PageSize构造函数,使用默认PageSize为15
     * 
@param pageName 分页的页面的相对URL,不包括后缀
     * 
@param pageExtension 页面的URL的后缀
     * 
@param itemSum Page上显示的List中的domainModel的总数
     * 
@param pageNo 页数
     
*/

    
public AbstractPagination(String pageName, String pageExtension,
        
int itemSum, int pageNo) {
        
super();

        
this.pageName = pageName;
        
this.pageExtension = pageExtension;
        
this.itemSum = itemSum;
        
this.pageNo = pageNo;
    }


    
/* (non-Javadoc)
     * @see com.goldnet.framework.util.paging.IPagination#getPageSum()
     
*/

    
public int getPageSum() {
        
if ((itemSum != -1&& (pageSize > 0)) {
            
return ((itemSum % pageSize) == 0? (itemSum / pageSize)
                                               : ((itemSum 
/ pageSize) + 1);
        }


        
return 0;
    }


    
/* (non-Javadoc)
     * @see com.goldnet.framework.util.paging.IPagination#getNextPageNo()
     
*/

    
public int getNextPageNo() {
        
return (pageNo < (getPageSum() - 1)) ? (pageNo + 1) : (getPageSum() -
        
1);
    }


    
/* (non-Javadoc)
     * @see com.goldnet.framework.util.paging.IPagination#getPrevPageNo()
     
*/

    
public int getPrevPageNo() {
        
return (pageNo > 0? (pageNo - 1) : 0;
    }


    
/* (non-Javadoc)
     * @see com.goldnet.framework.util.paging.IPagination#hasNextPage()
     
*/

    
public boolean hasNextPage() {
        
if (getPageSum() <= pageNo) {
            
return false;
        }


        
return true;
    }


    
/* (non-Javadoc)
     * @see com.goldnet.framework.util.paging.IPagination#hasPrevPage()
     
*/

    
public boolean hasPrevPage() {
        
if (pageNo <= 0{
            
return false;
        }


        
return true;
    }


    
/* (non-Javadoc)
     * @see com.goldnet.framework.util.paging.IPagination#addPageParameter(java.lang.String, java.lang.String)
     
*/

    
public void addPageParameter(String parameterName, String parameterValue) {
        PageParameter pp 
= new PageParameter(parameterName, parameterValue);
        
this.parameterList.add(pp);
    }


    
/* (non-Javadoc)
     * @see com.goldnet.framework.util.paging.IPagination#getPageUrl()
     
*/

    
public String getPageUrl() {
        String url 
= pageName + pageExtension;

        
if (parameterList.size() > 0{
            Iterator
<PageParameter> iterator = parameterList.iterator();
            PageParameter pageFirstParameter 
= iterator.next();
            url 
+= ("?" + pageFirstParameter.getParameterName() + "=" +
            pageFirstParameter.getParameterValue());

            
while (iterator.hasNext()) {
                PageParameter pageParameter 
= iterator.next();
                url 
+= ("&" + pageParameter.getParameterName() + "=" +
                pageParameter.getParameterValue());
            }

        }
 else {
            
//补充一个?解决附加分页参数时无?的问题
            url += "?";
        }


        
if (pageSize != DEFAULT_PAGE_SIZE) {
            url 
+= ("&" + PAGE_SIZE_KEY + "=" + pageSize);
        }


        
return url;
    }


    
/**
     * 子类必须覆盖的方法,用来计算分页的字符的方法
     
*/

    
public abstract void compilePaginationString();

    
/**
     * Getters & Setters
     
*/


    
/* (non-Javadoc)
     * @see com.goldnet.framework.util.paging.IPagination#getPageHtmlStr()
     
*/

    
public String getPageHtmlStr() {
        compilePaginationString();

        
return pageHtmlStr;
    }


    
/* (non-Javadoc)
     * @see com.goldnet.framework.util.paging.IPagination#getItemSum()
     
*/

    
public int getItemSum() {
        
return itemSum;
    }


    
/* (non-Javadoc)
     * @see com.goldnet.framework.util.paging.IPagination#setItemSum(int)
     
*/

    
public void setItemSum(int itemSum) {
        
this.itemSum = itemSum;
    }


    
/* (non-Javadoc)
     * @see com.goldnet.framework.util.paging.IPagination#getPageExtension()
     
*/

    
public String getPageExtension() {
        
return pageExtension;
    }


    
/* (non-Javadoc)
     * @see com.goldnet.framework.util.paging.IPagination#setPageExtension(java.lang.String)
     
*/

    
public void setPageExtension(String pageExtension) {
        
this.pageExtension = pageExtension;
    }


    
/* (non-Javadoc)
     * @see com.goldnet.framework.util.paging.IPagination#getPageName()
     
*/

    
public String getPageName() {
        
return pageName;
    }


    
/* (non-Javadoc)
     * @see com.goldnet.framework.util.paging.IPagination#setPageName(java.lang.String)
     
*/

    
public void setPageName(String pageName) {
        
this.pageName = pageName;
    }


    
/* (non-Javadoc)
     * @see com.goldnet.framework.util.paging.IPagination#getPageNo()
     
*/

    
public int getPageNo() {
        
return pageNo;
    }


    
/* (non-Javadoc)
     * @see com.goldnet.framework.util.paging.IPagination#setPageNo(int)
     
*/

    
public void setPageNo(int pageNo) {
        
this.pageNo = pageNo;
    }


    
/* (non-Javadoc)
     * @see com.goldnet.framework.util.paging.IPagination#getPageSize()
     
*/

    
public int getPageSize() {
        
return pageSize;
    }


    
/* (non-Javadoc)
     * @see com.goldnet.framework.util.paging.IPagination#setPageSize(int)
     
*/

    
public void setPageSize(int pageSize) {
        
this.pageSize = pageSize;
    }


    
public List<PageParameter> getParameterList() {
        
return parameterList;
    }


    
public void setParameterList(List<PageParameter> parameterList) {
        
this.parameterList = parameterList;
    }


    
/**
     * 分页参数,页面的QueryString形式都是?parameter=value的形式,此处为一对
     * 数据的抽象
     * 
@author Tin
     *
     
*/

    
private class PageParameter {
        
/**
             * 参数名称
             
*/

        
private String parameterName;

        
/**
             * 参数值
             
*/

        
private String parameterValue;

        
/**
             * 唯一构造函数
             * 
@param parameterName 参数名称
             * 
@param parameterValue 参数值
             
*/

        
public PageParameter(String parameterName, String parameterValue) {
            
this.parameterName = parameterName;
            
this.parameterValue = parameterValue;
        }


        
public String getParameterName() {
            
return parameterName;
        }


        
public String getParameterValue() {
            
return parameterValue;
        }

    }

}

  默认的分页实现:

package com.goldnet.framework.util.paging;


/**
 * 默认的分页实现
 * 
@author Tin
 *
 
*/

public class DefaultPagination extends AbstractPagination {
    
/**
    * 默认的构造函数
    * 
@param pageName 分页的页面的相对URL,不包括后缀
    * 
@param pageExtension 页面的URL的后缀
    * 
@param itemSum Page上显示的List中的domainModel的总数
    * 
@param pageNo 页数
    * 
@param pageSize 分页的大小
     
*/

    
public DefaultPagination(String pageName, String pageExtension,
        
int itemSum, int pageNo, int pageSize) {
        
super(pageName, pageExtension, itemSum, pageNo, pageSize);
    }


    
/**
         * 无PageSize构造函数,使用默认PageSize为15
     * 
@param pageName 分页的页面的相对URL,不包括后缀
     * 
@param pageExtension 页面的URL的后缀
     * 
@param itemSum Page上显示的List中的domainModel的总数
     * 
@param pageNo 页数
         
*/

    
public DefaultPagination(String pageName, String pageExtension,
        
int itemSum, int pageNo) {
        
super(pageName, pageExtension, itemSum, pageNo);
    }


    @Override
    
public void compilePaginationString() {
        String pageUrl 
= getPageUrl();
        pageHtmlStr 
= "\u5171 " + itemSum + " \u6761 &nbsp;\u7b2c " +
            (pageNo 
+ 1+ " \u9875 / \u5171 " + getPageSum() +
            
" \u9875&nbsp; <a href=\"" + pageUrl + "&" + PAGE_NO_KEY +
            "=0\">\u9996\u9875</a>&nbsp;&nbsp;<a href=\"" + pageUrl + "&" +
            PAGE_NO_KEY 
+ "=" + getPrevPageNo() +
            
"\">\u4e0a\u4e00\u9875</a> &nbsp;<a href=\"" + pageUrl + "&" +
            PAGE_NO_KEY 
+ "=" + getNextPageNo() +
            
"\">\u4e0b\u4e00\u9875</a> &nbsp;<a href=\"" + pageUrl + "&" +
            PAGE_NO_KEY 
+ "=" + (getPageSum() - 1+
            
"\">\u5c3e\u9875</a>&nbsp;&nbsp;\u6bcf\u9875\u663e\u793a" +
            pageSize + "\u6761";
    }

}


数字风格的实现:

/**
 *
 
*/

package com.goldnet.framework.util.paging;


/**
 * 数字页码风格的分页实现
 * 
@author Tin
 *
 
*/

public class PageNumberPagination extends AbstractPagination {
    
/**
     * 默认的构造函数
     * 
@param pageName 分页的页面的相对URL,不包括后缀
     * 
@param pageExtension 页面的URL的后缀
     * 
@param itemSum Page上显示的List中的domainModel的总数
     * 
@param pageNo 页数
     * 
@param pageSize 分页的大小
         
*/

    
public PageNumberPagination(String pageName, String pageExtension,
        
int itemSum, int pageNo, int pageSize) {
        
super(pageName, pageExtension, itemSum, pageNo, pageSize);
    }


    
/**
     * 无PageSize构造函数,使用默认PageSize为15
    * 
@param pageName 分页的页面的相对URL,不包括后缀
    * 
@param pageExtension 页面的URL的后缀
    * 
@param itemSum Page上显示的List中的domainModel的总数
    * 
@param pageNo 页数
     
*/

    
public PageNumberPagination(String pageName, String pageExtension,
        
int itemSum, int pageNo) {
        
super(pageName, pageExtension, itemSum, pageNo);
    }


    
/* (non-Javadoc)
     * @see com.goldnet.framework.util.paging.AbstractPagination#compilePaginationString()
     
*/

    @Override
    
public void compilePaginationString() {
        String pageUrl 
= getPageUrl();
        StringBuffer returnString 
= new StringBuffer();
        returnString.append(
"\u5171 " + itemSum + " \u6761 &nbsp;\u7b2c " +
            (pageNo 
+ 1+ " \u9875 / \u5171 " + getPageSum() +
            
" \u9875&nbsp; <a href=\"" + pageUrl + "&" + PAGE_NO_KEY + "=" +
            getPrevPageNo() + "\">&lt;&lt;</a>&nbsp;");

        
for (int page = 0; page < getPageSum(); page++{
            
if(page!=pageNo){
                returnString.append(
"<a href=\""+pageUrl +"&"+PAGE_NO_KEY + "=" + page +"\">"+(page+1)+"</a>&nbsp;");
            }
 else {
                returnString.append(
"<a href=\""+pageUrl +"&"+PAGE_NO_KEY + "=" + page +"\"><span style=\"background:black;color:#eee;font-size:120%;padding-left:5px;padding-right:5px;text-align:center;\">"+(page+1)+"</span></a>&nbsp;");
            }

        }


        returnString.append(
"&nbsp;<a href=\"" + pageUrl + "&" +
            PAGE_NO_KEY + "=" + getNextPageNo() +
            
"\">&gt;&gt;</a> &nbsp;&nbsp;\u6bcf\u9875\u663e\u793a" + pageSize +
            "\u6761");
        pageHtmlStr 
= returnString.toString();
    }

}


测试类,用的JUnit3,其实JUnit4更优雅:D
package com.goldnet.test.unittest.framework.paging;

import junit.framework.TestCase;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.goldnet.framework.util.paging.DefaultPagination;
import com.goldnet.framework.util.paging.IPagination;
import com.goldnet.framework.util.paging.PageNumberPagination;

public class TestPagination extends TestCase {
    
protected transient final Log log = LogFactory.getLog(getClass());

    
protected void setUp() throws Exception {
        
super.setUp();
    }


    
protected void tearDown() throws Exception {
        
super.tearDown();
    }


    
public void testDefaultPainationWith3Parameters() {
        IPagination p 
= new DefaultPagination("test",".action",50,2);
        p.addPageParameter(
"a","b");
        p.addPageParameter(
"c","234");
        p.addPageParameter(
"e.ddd","34234adbb");
        log.info(p.getPageHtmlStr());
    }

    
    
public void testDefaultPainationWith1Parameters() {
        IPagination p 
= new DefaultPagination("test",".action",50,2);
        p.addPageParameter(
"a","b");
        log.info(p.getPageHtmlStr());
    }

    
    
public void testDefaultPainationWithNoParameters() {
        IPagination p 
= new DefaultPagination("test",".action",50,2);
        log.info(p.getPageHtmlStr());
    }

    
    
public void testDefaultPainationWith3ParametersAndCustomPageSize() {
        IPagination p 
= new DefaultPagination("test",".action",50,2,5);
        p.addPageParameter(
"a","b");
        p.addPageParameter(
"c","234");
        p.addPageParameter(
"e.ddd","34234adbb");
        log.info(p.getPageHtmlStr());
    }

    
    
public void testDefaultPainationWithNoParametersAndCustomPageSize() {
        IPagination p 
= new DefaultPagination("test",".action",50,2,5);
        log.info(p.getPageHtmlStr());
    }

    
    
public void testPageNumberPainationWith3Parameters() {
        IPagination p 
= new PageNumberPagination("test",".action",50,2);
        p.addPageParameter(
"a","b");
        p.addPageParameter(
"c","234");
        p.addPageParameter(
"e.ddd","34234adbb");
        log.info(p.getPageHtmlStr());
    }

    
    
public void testPageNumberPainationWith1Parameters() {
        IPagination p 
= new PageNumberPagination("test",".action",50,2);
        p.addPageParameter(
"a","b");
        log.info(p.getPageHtmlStr());
    }

    
    
public void testPageNumberPainationWithNoParameters() {
        IPagination p 
= new PageNumberPagination("test",".action",50,2);
        log.info(p.getPageHtmlStr());
    }

    
    
public void testPageNumberPainationWith3ParametersAndCustomPageSize() {
        IPagination p 
= new PageNumberPagination("test",".action",50,2,5);
        p.addPageParameter(
"a","b");
        p.addPageParameter(
"c","234");
        p.addPageParameter(
"e.ddd","34234adbb");
        log.info(p.getPageHtmlStr());
    }

    
    
public void testPageNumberPainationWithNoParametersAndCustomPageSize() {
        IPagination p 
= new PageNumberPagination("test",".action",50,2,5);
        log.info(p.getPageHtmlStr());
    }

}


说实话这么丑陋的东西本不愿意现眼……但是实在没什么可发的,应朋友所托共享出来。
特 点就是分页逻辑不管你用hibernate、JDBC、iBatis或者什么其他的,都可以和它一起工作,因为我任为对于DAO或者Action来说分页 逻辑就应该是pageSize、Pageno、itemSum这几个参数的传递,具体的显示上的问题应该交给第三方来负责,如taglib什么的,所以才 写了这样的实现。而且这个实现应该容易扩展。配合js跳转(css也应该抽出)等可以实现更多风格:D
posted on 2006-04-03 02:22 Leo 阅读(465) 评论(2)  编辑  收藏 所属分类: 技术随文

评论

# re: 分页的轻量实现 2006-06-21 13:33 anyang
蹭分,走人!  回复  更多评论
  

# re: 分页的轻量实现 2006-06-21 14:01 anyang
蹭分,走人!again  回复  更多评论
  


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


网站导航: