J2EE开发中分页组件总结

本文介绍了一种在J2EE开发环境下使用Hibernate进行高效分页的方法。通过自定义标签和核心处理类实现了灵活且易用的分页功能,支持通过HQL和Criteria进行分页查询。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

J2EE开发中少不了要用到分页的。在持久层Hibernate中已支持了原生的分页查找记录。为了便于开发高效的进行。现将开发中用到的记录下来。一起讨论讨论

方法一:
页面分页用标签的形式

页面标签处理

public class PageControllerTag extends BodyTagSupport {

private String gotoUrl;

private static final int DEFAULTPAGESIZE = Integer.parseInt(Constants.PAGE_DEFAULT_LIMIT);

public static final String TOTAL = "total";

private static final String PAGE_NO = "pageNo";

private static final String RECORD_COUNT = "pageSize";

@SuppressWarnings("unchecked")
@Override
public int doStartTag() throws JspException {
int pageNo = 1;

int total = 0;

int totalPage = 1;

HttpServletRequest request = (HttpServletRequest)pageContext.getRequest();

StringBuffer sb = new StringBuffer();

sb.append("\r\n<form method=\"post\" action=\"\"").append(
"name=\"pageController\">\r\n");

Enumeration enumeration = request.getParameterNames();
String name = null;
String value = null;

while (enumeration.hasMoreElements()) {
name = (String) enumeration.nextElement();
value = request.getParameter(name);

if (name.equals(RECORD_COUNT)) {
continue;
}

if (name.equals(PAGE_NO)) {
if (null != value && !"".equals(value)) {
pageNo = Integer.parseInt(value);
}

continue;
}

sb.append("<input type=\"hidden\" name=\"").append(name).
append("\" value=\"").append(value).append("\"/>\r\n");

}

sb.append("<input type='hidden' name=\"").append(PAGE_NO).append(
"\" value=\"").append(pageNo).append("\"/>\r\n");

String tot = (String)request.getAttribute(TOTAL);

if (null != tot && !"".equals(tot)) {
total = Integer.parseInt(tot);
}

totalPage = getTotalPage(total);

sb.append("<br/>\r\n");
sb.append(" \r\n");
sb.append("共").append(totalPage).append("页  当前第").
append(pageNo).append("页\r\n");
sb.append(" \r\n");

if (pageNo == 1) {
sb.append("首页");
sb.append(" ");
sb.append("上一页\r\n");
} else {
sb.append("<a href=\"#\" onclick=\"turnOverPage(1)\">首页</a>\r\n");
sb.append(" ");
sb.append("<a href=\"#\" onclick=\"turnOverPage('").append((pageNo - 1)).
append("')\">上一页</a>\r\n");
}

sb.append(" ");
if (pageNo == totalPage) {
sb.append("下一页");
sb.append(" ");
sb.append("尾页\r\n");
} else {
sb.append("<a href=\"#\" onclick=\"turnOverPage(").
append((pageNo + 1)).append(")\">下一页</a>\r\n");
sb.append(" ");
sb.append("<a href=\"#\" onclick=\"turnOverPage(").
append(totalPage).append(")\">尾页</a>\r\n");
}

sb.append(" ");

sb.append("跳转到<select onChange=\"turnOverPage(this.value)\">\r\n");

for (int i = 1; i <= totalPage; i++) {
if (i == pageNo) {
sb.append(" <option value=\"").append(i).
append("\" selected>第").append(i).append("页</option>\r\n");
} else {
sb.append(" <option value=\"").append(i).
append("\">第").append(i).append("页</option>\r\n");
}
}

sb.append("</select>\r\n");
sb.append(" \r\n");
sb.append("</form>\r\n");

sb.append("<script language=\"javascript\">\r\n");
sb.append(" function turnOverPage(no){\r\n");
sb.append(" var form = document.pageController;\r\n");
sb.append(" //页号越界处理\r\n");
sb.append(" if (no").append(">").append(totalPage).append("){\r\n");
sb.append(" no=").append(totalPage).append(";\r\n");
sb.append(" }\r\n");

sb.append(" if (no").append("<=0){\r\n");
sb.append(" no=1;\r\n");
sb.append(" }\r\n");

sb.append(" form.").append(PAGE_NO).append(".value=no;\r\n");
sb.append(" form.action=\"").append(gotoUrl).append("\";\r\n");
sb.append(" form.submit();\r\n");
sb.append(" }\r\n");
sb.append("</script>\r\n");

try {
pageContext.getOut().print(sb.toString());
} catch (IOException e) {
e.printStackTrace();
}

return super.doStartTag();
}

public String getGotoUrl() {
return gotoUrl;
}

public void setGotoUrl(String gotoUrl) {
this.gotoUrl = gotoUrl;
}

/**
* 根据总记录数得到总页数
*
* @return int 总页数
*/
private int getTotalPage(int total) {

int totalPage = 1;
if (total == 0) {
totalPage = 1;
} else {
totalPage = (total % DEFAULTPAGESIZE == 0) ? (total / DEFAULTPAGESIZE) : (total
/ DEFAULTPAGESIZE + 1);
}

return totalPage;
}

}


以上没加上 样式,有些丑陋
定义了分页标签,肯定得需要定义标签


<?xml version="1.0" encoding="UTF-8" ?>

<taglib xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"
version="2.0">

<tlib-version>1.0</tlib-version>
<short-name>pageControllerTag</short-name>
<uri>http://code.google.com/samung/tag1.0</uri>

<tag>
<name>paginator</name>
<tag-class>com.chinadim.cpa.core.dao.support.PageControllerTag</tag-class>
<body-content>scriptless</body-content>
<attribute>
<name>gotoUrl</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>

</taglib>


核心的处理分页记录的类

/**
* 分页查询函数,使用hql.
*
* @param pageNo 页号,从1开始.
*/
public Page pagedQuery(String hql, int pageNo, int pageSize, Object... values) {
Assert.hasText(hql);
Assert.isTrue(pageNo >= 1, "pageNo should start from 1");
int startIndex = Page.getStartOfPage(pageNo, pageSize);
return pagedQueryWithStartIndex(hql, startIndex, pageSize, values);
}

/**
* 分页查询函数,使用已设好查询条件与排序的<code>Criteria</code>.
*
* @param pageNo 页号,从1开始.
* @return 含总记录数和当前页数据的Page对象.
*/
public Page pagedQuery(Criteria criteria, int pageNo, int pageSize) {
Assert.notNull(criteria);
Assert.isTrue(pageNo >= 1, "pageNo should start from 1");
int startIndex = Page.getStartOfPage(pageNo, pageSize);
return pageQueryWithStartIndex(criteria, startIndex, pageSize);
}

/**
* 分页查询函数,使用hql.
*
* @param pageNo 页号,从1开始.
*/
public Page pagedQueryWithStartIndex(String hql, int startIndex, int pageSize, Object... values) {
Assert.hasText(hql);
Assert.isTrue(startIndex >= 0, "pageNo should start from 1");
// Count查询
String countQueryString = " select count (*) " + removeSelect(removeOrders(hql));
List countlist = getHibernateTemplate().find(countQueryString, values);
long totalCount = (Long) countlist.get(0);
if (totalCount < 1)
return new Page();
Query query = createQuery(hql, values);
List list = query.setFirstResult(startIndex).setMaxResults(pageSize).list();
return new Page(startIndex, totalCount, pageSize, list);
}

/**
* 分页查询函数,根据查询条件进行查询 使用startIndex作为参数进行查询
* @param criteria
* @param start
* @param pageSize
* @return
*/
public Page pageQueryWithStartIndex(Criteria criteria, int startIndex, int pageSize){
Assert.notNull(criteria);
Assert.isTrue(startIndex >= 0, "start index should start from 1");
CriteriaImpl impl = (CriteriaImpl) criteria;

// 先把Projection和OrderBy条件取出来,清空两者来执行Count操作
Projection projection = impl.getProjection();
List<CriteriaImpl.OrderEntry> orderEntries;
try {
orderEntries = (List) BeanUtils.forceGetProperty(impl, "orderEntries");
BeanUtils.forceSetProperty(impl, "orderEntries", new ArrayList());
} catch (Exception e) {
throw new InternalError(" Runtime Exception impossibility throw ");
}

// 执行查询
int totalCount = (Integer) criteria.setProjection(Projections.rowCount()).uniqueResult();

// 将之前的Projection和OrderBy条件重新设回去
criteria.setProjection(projection);
if (projection == null) {
criteria.setResultTransformer(CriteriaSpecification.ROOT_ENTITY);
}

try {
BeanUtils.forceSetProperty(impl, "orderEntries", orderEntries);
} catch (Exception e) {
throw new InternalError(" Runtime Exception impossibility throw ");
}

// 返回分页对象
if (totalCount < 1)
return new Page();


List list = criteria.setFirstResult(startIndex).setMaxResults(pageSize).list();
return new Page(startIndex, totalCount, pageSize, list);
}

/**
* 分页查询函数,根据entityClass和查询条件参数创建默认的<code>Criteria</code>.
*
* @param pageNo 页号,从1开始.
* @return 含总记录数和当前页数据的Page对象.
*/
public Page pagedQuery(Class entityClass, int pageNo, int pageSize, Criterion... criterions) {
Criteria criteria = createCriteria(entityClass, criterions);
return pagedQuery(criteria, pageNo, pageSize);
}

/**
* 分页查询函数,根据entityClass和查询条件参数,排序参数创建默认的<code>Criteria</code>.
*
* @param pageNo 页号,从1开始.
* @return 含总记录数和当前页数据的Page对象.
*/
public Page pagedQuery(Class entityClass, int pageNo, int pageSize, String orderBy, boolean isAsc,
Criterion... criterions) {
Criteria criteria = createCriteria(entityClass, orderBy, isAsc, criterions);
return pagedQuery(criteria, pageNo, pageSize);
}



Page类操作

public class Page implements Serializable {

private static final long serialVersionUID = 1L;

private static final int DEFAULT_PAGE_SIZE = Integer.parseInt(Constants.PAGE_DEFAULT_LIMIT);

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

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

private Object data; // 当前页中存放的记录,类型一般为List

private long totalCount; // 总记录数

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

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

/**
* 取总记录数.
*/
public long getTotalCount() {
return this.totalCount;
}

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

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

/**
* 取当前页中的记录.
*/
public Object getResult() {
return data;
}

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

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

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

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

/**
* 获取任一页第一条数据在数据集的位置.
*
* @param pageNo 从1开始的页号
* @param pageSize 每页记录条数
* @return 该页第一条数据
*/
public static int getStartOfPage(int pageNo, int pageSize) {
return (pageNo - 1) * pageSize;
}
}


具体的ACTION应用和页面加载

private String pageNo = "1";

private String total = "0";

public String getTotal() {
return total;
}

public void setTotal(String total) {
this.total = total;
}

public String getPageNo() {
return pageNo;
}

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

@SuppressWarnings("unchecked")
public String showJspTagList() throws Exception {
Page page = cpaInfoTestManager.findPaginatorByAllConditions(
Integer.parseInt(pageNo), Integer.parseInt(Constants.PAGE_DEFAULT_LIMIT));

total = String.valueOf(page.getTotalCount());
cpaInfoTestList = (List<CpaInfoTest>)page.getResult();

return SUCCESS;
}


页面部分加载

<%@ taglib uri="http://code.google.com/samung/tag1.0" prefix="myTag" %>

<myTag:paginator gotoUrl="${pageContext.request.contextPath}/cpatest/showJspTagList.action"></myTag:paginator>


第一种方式即可实现分页

第二种方式是差不多的,只是没用到自定义的标签

@SuppressWarnings("unchecked")
public class Page {

public static final int DEFAULT_PAGE_SIZE = 20;

public static final int DEFAULT_PAGE = 1;


private String url;

private int currentPage = 1;

private int pageSize = DEFAULT_PAGE_SIZE;


private long totalCount = -1;


private long totalPage;

private List data;

public Page() {
super();
}

public Page(int currentPage) {
this.currentPage = currentPage;
}

public Page(int currentPage, int pageSize) {
this.currentPage = currentPage;
this.pageSize = pageSize;
}


public int getStart() {
return (getCurrentPage() - 1) * pageSize;
}


public int getCurrentPage() {
if (currentPage > getTotalPage()) {
return (int) getTotalPage();
} else if (currentPage < 1) {
return 1;
} else {
return currentPage;
}
}


public void setCurrentPage(int currentPage) {
this.currentPage = currentPage;
}


public List getData() {
return data;
}

public void setData(List data) {
this.data = data;
}

public int getPageSize() {
return pageSize;
}

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

public long getTotalCount() {
return totalCount;
}

public void setTotalCount(long totalCount) {
this.totalCount = totalCount;
}

public long getTotalPage() {
if (totalCount % pageSize == 0) {
totalPage = totalCount / pageSize;
return totalPage;
} else {
totalPage = totalCount / pageSize + 1;
return totalPage;
}
}

public String getUrl() {
return url;
}

public void setUrl(String url) {
this.url = url;
}
}



Page帮助类

public class PageHelper {

public static Page getPageFromRequest(HttpServletRequest request) {
return getPageFromRequest(request, 0);
}

public static Page getPageFromRequest(HttpServletRequest request,
int pageSize) {
Page page = new Page();

int currentPage = 1;

StringBuffer querySb = new StringBuffer();
Map paramMap = request.getParameterMap();
for (Iterator it = paramMap.keySet().iterator(); it.hasNext();) {

String key = (String) it.next();

if (key.equals("page")) {
String[] values = (String[]) paramMap.get(key);
String str = values[0];
if (str.equals(""))
continue;
try {
currentPage = Integer.parseInt(str);
} catch (Exception e) {
currentPage = Page.DEFAULT_PAGE;
}
continue;
}

String[] values = (String[]) paramMap.get(key);

if (key.equals("pageSize")) {

String str = values[0];
try {
pageSize = Integer.parseInt(str);
} catch (Exception e) {
}
}

for (int i = 0; i < values.length; i++) {
try {
querySb.append("&" + key + "="
+ URLEncoder.encode(values[i], "GBK"));
} catch (UnsupportedEncodingException e) {

e.printStackTrace();
}
}
}

if (querySb.length() != 0) {
querySb.setCharAt(0, '?');
querySb.append('&');
} else {
querySb.append('?');
}

page.setCurrentPage(currentPage);

if (pageSize != 0)
page.setPageSize(pageSize);

page.setUrl(request.getRequestURL().append(querySb).toString());

return page;
}
}



PaginationUtils类

public class PaginationUtils {
private static DateFormat FMT = new SimpleDateFormat("yyyy-MM-dd hh:mm");

public static String notNull(Object value, String out) {
return value == null ? out : value.toString();
}

public static String notNull(Object value) {
return notNull(value, "");
}

public static String notZero(int value, String out) {
return value == 0 ? out : String.valueOf(value);
}

public static String notZero(int value) {
return notZero(value, "");
}

public static String formatDate(Calendar date) {
return FMT.format(date.getTime());
}

public static String createPageNavigator(Page page) {
// 第?页 共?页上一页下一页 跳转到?
StringBuffer sb = new StringBuffer();

sb.append("<span>").append("第 ").append(page.getCurrentPage())
.append(" 页 ").append("共 ").append(
page.getTotalPage()).append(" 页 ").append(
"共 ").append(page.getTotalCount()).append(
" 条 ");

if (page.getCurrentPage() > 1) {
sb.append("<a href=\"").append(page.getUrl()).append("page=")
.append(1).append("\">首页</a> ");
sb.append("<a href=\"").append(page.getUrl()).append("page=")
.append(page.getCurrentPage() - 1).append(
"\">上一页</a> ");
}

if (page.getCurrentPage() < page.getTotalPage()) {
sb.append("<a href=\"").append(page.getUrl()).append("page=")
.append(page.getCurrentPage() + 1).append(
"\">下一页</a> ");
sb.append("<a href=\"").append(page.getUrl()).append("page=")
.append(page.getTotalPage()).append("\">末页</a> ");
}

sb.append("</span>");
return sb.toString();
}

public static void main(String[] args) {

}
}



具体应用上的


private Page pageList;

@SuppressWarnings("unchecked")
public String cpaAccountList() throws Exception {
//填充到map对象,用于页面取
cpaUserKeyMap.clear();
cpaUserKeyMap.putAll(fillCpaUserKey());

pageList = PageHelper.getPageFromRequest(getRequest());
pageList = cpaAccountManager.fetchAllCpaAccountList(cpaAccount, pageList);
return SUCCESS;
}


jsp页面直接用struts2的标签输出即可

<ww:text name="%{@com.chinadim.cpa.utils.PaginationUtils@createPageNavigator(pageList)}"/>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值