基于Struts2的Hibernate分页实现(FreeMarker进行视图解析)
在进行Web开发时,很多地方要使用到分页这个技术。.NET框架中是直接集成好的控件,可以直接使用了。而Java中没有,需要程序员自己来编写实现过程。虽然分页过程并不复杂,但是要完美的实现是需要时间来考验的。
先说说分页的基本原理,分页显示就是在数据量大时页面上可以只显示所有数据的一部分,然后点击页面连接可以跳到所需的位置继续查看。需求很明确,实现方法大致分为两种:一种是物理分页,也就是真分页,这种方法是在SQL语句上写获取数据量的关键字然后进行数据库检索,只取出那一部分结果,需要查看其他页时再次进行数据库检索。二是全部结果一次提出,然后再浏览器页面上进行分页,这种方式一般借助JS来完成,当前不少前端框架都自行实现了分页,效果很不错,比如YUI,那么我们先看一个YUI的示例。效果图如下:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><title>State of Vehicle</title></head><body style="background-color:#e6ecf4"><div id="resultShow" style="margin-top:10px;width: 998px;display: none;"><b id="resultSet"></div> </div></div><b name="code">YAHOO.example.Data = {areacodes : []};function initStatusResultTable(){var myColumn=[{key:"owner",label:"车主",width:160,resizeable:true,sortable:true},{key:"plate",label:"车牌号",width:160,resizeable:true,sortable:true},{key:"title",label:"当前状态",width:190,resizeable:true,sortable:true}];var myDataSource=new YAHOO.util.DataSource(YAHOO.example.Data.areacodes);myDataSource.responseType = YAHOO.util.DataSource.TYPE_JSARRAY;myDataSource.responseSchema = {fields: ["owner","plate","title","newTime"]};var myConfigs = { paginator: new YAHOO.widget.Paginator({rowsPerPage: 10,template: YAHOO.widget.Paginator.TEMPLATE_ROWS_PER_PAGE,rowsPerPageOptions: [10,25,50,100],pageLinks: 5}),draggableColumns:true}var myDataTable = new YAHOO.widget.DataTable("resultSet", myColumn, myDataSource, myConfigs);}function queryStatus(){var callback={success:function(o){var clist = YAHOO.lang.JSON.parse(o.responseText);var list = clist.resList;//获取返回的Listvar shows = "";if (list.length > 0) {for (var i = 0; i < list.length; i++) {shows += "YAHOO.example.Data.areacodes[YAHOO.example.Data.areacodes.length]={ owner:""+ list[i].owner+ "","+ "plate:""+ list[i].plate+ "","+ "title:""+ list[i].title+ ""};";}} else {shows = "YAHOO.example.Data.areacodes.length=0;";}eval("YAHOO.example.Data.areacodes.length=0;");eval(shows.toString() + " " + "initStatusResultTable();");Dom.get('resultShow').style.display = 'block';},failure:function(o){alert('ajax请求失败,请检查网络!');}};var surl = 'xxx.action';var postData ='';YAHOO.util.Connect.asyncRequest('post',surl,callback,postData);}package xxx.core.common;import java.util.*;import xxx.core.Constants;import org.hibernate.Hibernate;import org.hibernate.Query;import org.hibernate.Session;import org.springframework.orm.hibernate3.HibernateTemplate;import org.springframework.orm.hibernate3.support.HibernateDaoSupport;/** * Hibernate分页查询辅助类(目前仅支持HQL方式) * * @author Sarin * */public class PagingListHt extends HibernateDaoSupport {private int rowCount = 0; // 记录总数private int pageCount = 1; // 分页总数private int pageSize = Constants.DEFAULT_PAGE_SIZE; // 每页记录数private int pageNum = 1; // 当前页数private int startIndex = 1; // 起始记录数private int endIndex = 1; // 结束记录数private List list = new ArrayList();// 记录列表/** * 获得对象列表 */public List getList() {return list;}/* 获得起始记录数 */public int getStartIndex() {return startIndex;}public Integer getStartIndexInteger() {return new Integer(startIndex);}/* 获得结束记录数 */public int getEndIndex() {return endIndex;}public Integer getEndIndexInteger() {return new Integer(endIndex);}/* 获得分页其它信息 */public int getPageCount() {return pageCount;}public int getPageNum() {return pageNum;}public int getPageSize() {return pageSize;}public int getRowCount() {return rowCount;}/** * 构造方法,HQL无参数,单对象 * * @param hibernateTemplate ht对象 * @param pageNum 第几页 * @param pageSize 每页显示数目 * @param hql HQL语句 * @param clazz 对象类型 */public PagingListHt(HibernateTemplate hibernateTemplate, int pageNum,int pageSize, String hql, Class clazz) {preProcessParams(pageNum, pageSize);execute(hibernateTemplate, pageNum, pageSize, hql, clazz);}/** * 构造方法,HQL无参数,多对象 * * @param hibernateTemplate * @param pageNum * @param pageSize * @param hql */public PagingListHt(HibernateTemplate hibernateTemplate, int pageNum,int pageSize, String hql) {preProcessParams(pageNum, pageSize);execute(hibernateTemplate, pageNum, pageSize, hql);}/** * 构造方法,HQL有参数,单对象 * * @param hibernateTemplate ht对象 * @param pageNum 第几页 * @param pageSize 每页显示数目 * @param hql HQL语句 * @param parameters Object[]类型的参数 * @param clazz 对象类型 */public PagingListHt(HibernateTemplate hibernateTemplate, int pageNum,int pageSize, String hql, Object[] parameters, Class clazz) {preProcessParams(pageNum, pageSize);execute(hibernateTemplate, pageNum, pageSize, hql, parameters, clazz);}/** * 构造方法,HQL有参数,多对象 * * @param hibernateTemplate * @param pageNum * @param pageSize * @param hql * @param parameters */public PagingListHt(HibernateTemplate hibernateTemplate, int pageNum,int pageSize, String hql, Object[] parameters) {preProcessParams(pageNum, pageSize);execute(hibernateTemplate, pageNum, pageSize, hql, parameters);}/** * 预处理页面参数 */private void preProcessParams(int pageNum, int pageSize) {if (pageNum > 0) {this.pageNum = pageNum;}if (pageSize > 0) {this.pageSize = pageSize;}if (pageSize > Constants.MAX_PAGE_SIZE) {this.pageSize = Constants.MAX_PAGE_SIZE;}}/** * 根据给定的数据计算相关分页信息,多对象HQL * * @param hibernateTemplate * @param pageNum * @param pageSize * @param hql */private void execute(HibernateTemplate hibernateTemplate, int pageNum,int pageSize, String hql) {// 获取Hibernate当前的SessionSession session = hibernateTemplate.getSessionFactory().getCurrentSession();// 获取记录总数this.rowCount = hibernateTemplate.find(hql).size();// 计算分页数及起止记录countPage();// 获取Listlist = session.createQuery(hql).setFirstResult((pageNum - 1) * pageSize).setMaxResults(pageSize).list();}/** * 根据给定的数据计算相关分页信息,单对象HQL,且无where限制条件 * * @param hibernateTemplate * @param pageNum * @param pageSize * @param hql * @param clazz */private void execute(HibernateTemplate hibernateTemplate, int pageNum,int pageSize, String hql, Class clazz) {// 获取Hibernate当前的SessionSession session = hibernateTemplate.getSessionFactory().getCurrentSession();// 获取记录总数this.rowCount = Integer.parseInt(String.valueOf(session.createQuery("select count(*) from " + clazz.getName()).uniqueResult()));// 计算分页数及起止记录countPage();// 获取Listlist = session.createQuery(hql).setFirstResult((pageNum - 1) * pageSize).setMaxResults(pageSize).list();}/** * 重载的分页方法,接受预编译HQL语句,HQL单对象且无where限制条件 * * @param hibernateTemplate * @param pageNum * @param pageSize * @param hql * @param parameters * @param clazz */private void execute(HibernateTemplate hibernateTemplate, int pageNum,int pageSize, String hql, Object[] parameters, Class clazz) {// 获取Hibernate当前的SessionSession session = hibernateTemplate.getSessionFactory().getCurrentSession();// 获取记录总数this.rowCount = Integer.parseInt(String.valueOf(session.createQuery("select count(*) from " + clazz.getName()).uniqueResult()));// 计算分页数及起止记录countPage();// 预编译HQL语句Query query = session.createQuery(hql);// 为预编译HQL语句设置参数for (int i = 0; i < parameters.length; i++) {query.setParameter(i, String.valueOf(parameters[i]),Hibernate.STRING);}// 获取Listlist = query.setFirstResult((pageNum - 1) * pageSize).setMaxResults(pageSize).list();}/** * 重载的分页方法,接受预编译HQL语句,HQL多对象 * * @param hibernateTemplate * @param pageNum * @param pageSize * @param hql * @param parameters */private void execute(HibernateTemplate hibernateTemplate, int pageNum,int pageSize, String hql, Object[] parameters) {// 获取Hibernate当前的SessionSession session = hibernateTemplate.getSessionFactory().getCurrentSession();// 获取记录总数this.rowCount = hibernateTemplate.find(hql, parameters).size();// 计算分页数及起止记录countPage();// 预编译HQL语句Query query = session.createQuery(hql);// 为预编译HQL语句设置参数for (int i = 0; i < parameters.length; i++) {query.setParameter(i, String.valueOf(parameters[i]),Hibernate.STRING);}// 获取Listlist = query.setFirstResult((pageNum - 1) * pageSize).setMaxResults(pageSize).list();}/** * 计算分页数及起止记录 */private void countPage() {// 计算分页总数if ((rowCount % pageSize) == 0) {pageCount = rowCount / pageSize;} else {pageCount = rowCount / pageSize + 1;}if (pageCount == 0) {pageCount = 1;}// 判断pageNum是否过界if (pageNum > pageCount && rowCount != 0) {pageNum = pageCount;}// 计算起止记录startIndex = (pageNum - 1) * pageSize + 1;endIndex = (pageNum) * pageSize;}}/* 默认分页尺寸及分页标记 */public static final int DEFAULT_PAGE_SIZE = 10;public static final int MAX_PAGE_SIZE = 1000;public static final String NORMAL_MARK = "?";public static final String START_MARK = ":_START_INDEX_";public static final String END_MARK = ":_END_INDEX_";/* 默认编码方式 */public static final String ENCODING = "UTF-8";
<#-- 处理分页参数 --><#function getPageUrl pageNum><#local pageUrl=base+fullUrlWithoutPageInfo><#if pageUrl?ends_with("?")><#return pageUrl + "pageSize=" + pageSize + "&pageNum=" + pageNum><#else><#return pageUrl + "&pageSize=" + pageSize + "&pageNum=" + pageNum></#if></#function><#-- 全部或分页显示 --><#function getPageUrlResize size><#local pageUrl=base+fullUrlWithoutPageInfo><#if pageUrl?ends_with("?")><#return pageUrl + "pageNum=1&pageSize=" + size><#else><#return pageUrl + "&pageNum=1&pageSize=" + size></#if></#function><#-- 分页信息 --><#macro paging pagingListHt><#local pageCount=pagingListHt.pageCount><#local rowCount=pagingListHt.rowCount><#local pageNum=pagingListHt.pageNum><#local pageSize=pagingListHt.pageSize><#if rowCount == 0><#if useFlag?exists><div style="border:1px solid #666;padding:2 5 2 5;background:#efefef;color:#333">没有相关记录</div><#else><#assign useFlag = 1></#if><#else><table><tr><td style="line-height:150%">共 ${rowCount} 条记录 ${pageCount} 页 <#if pageCount gt 1 && pageSize!=maxPageSize><span style="padding:2px 3px 0 3px"><a href="${getPageUrlResize(maxPageSize)}">全部显示</a></span><#elseif pageSize==maxPageSize><span style="padding:2px 3px 0 3px"><a href="${getPageUrlResize(defaultPageSize)}">分页显示</a></span></#if><#if (pageCount <= 11)><#local startPage = 1><#local endPage = pageCount><#elseif (pageNum + 5 > pageCount)><#local startPage = pageCount - 10><#local endPage = pageCount><#elseif (pageNum - 5 < 1)><#local startPage = 1><#local endPage = 11><#else><#local startPage = pageNum - 5><#local endPage = pageNum + 5></#if><#if (pageCount > 1)><#if (pageNum != 1)><#if (pageCount > 11)><a href="${getPageUrl(1)}" style="font-family:Webdings" title="首页">9</a></#if><a href="${getPageUrl(pageNum-1)}" style="font-family:Webdings" title="上页">3</a><#else><#if (pageCount > 11)><span style="font-family:Webdings;color:#999">9</span></#if><span style="font-family:Webdings;color:#999">3</span></#if><#list startPage..endPage as x><#if x=pageNum><span href="${getPageUrl(x)}">${x}</a></span></#if></#list><#if (pageCount != pageNum)><a href="${getPageUrl(pageNum+1)}" style="font-family:Webdings" title="下页">4</a><#if (pageCount > 11)><a href="${getPageUrl(pageCount)}" style="font-family:Webdings" title="尾页">:</a></#if><#else><span style="font-family:Webdings;color:#999">4</span><#if (pageCount > 11)><span style="font-family:Webdings;color:#999">:</span></#if></#if></#if></#if></td></tr></table></#macro>/* 分页信息 */protected int pageNum = 1;protected int pageSize = Constants.DEFAULT_PAGE_SIZE;public int getPageNum() {return pageNum;}public void setPageNum(int pageNum) {this.pageNum = pageNum;}public int getPageSize() {return pageSize;}public void setPageSize(int pageSize) {this.pageSize = pageSize;}public int getMaxPageSize() {return Constants.MAX_PAGE_SIZE;}public int getDefaultPageSize() {return Constants.DEFAULT_PAGE_SIZE;}public String getQueryStringWithoutPageNum() {Map m = getParameters();m.remove("pageNum");return QueryUtil.getQueryString(m);}public String getFullUrlWithoutPageNum() {return getRequest().getServletPath() + "?"+ getQueryStringWithoutPageNum();}public String getQueryStringWithoutPageInfo() {Map m = getParameters();m.remove("pageNum");m.remove("pageSize");return QueryUtil.getQueryString(m);}public String getFullUrlWithoutPageInfo() {return getRequest().getServletPath() + "?"+ getQueryStringWithoutPageInfo();}package xxx.core.util;import java.io.UnsupportedEncodingException;import java.net.URLEncoder;import java.util.Iterator;import java.util.Map;import javax.servlet.http.HttpServletRequest;import xxx.core.Constants;public class QueryUtil {/** * 将请求参数还原为key=value的形式 * * @param params * @return */public static String getQueryString(Map<String, Object> params) {StringBuffer queryString = new StringBuffer(256);Iterator it = params.keySet().iterator();int count = 0;while (it.hasNext()) {String key = (String) it.next();String[] param = (String[]) params.get(key);for (int i = 0; i < param.length; i++) {if (count == 0) {count++;} else {queryString.append("&");}queryString.append(key);queryString.append("=");try {queryString.append(URLEncoder.encode((String) param[i],Constants.ENCODING));} catch (UnsupportedEncodingException e) {}}}return queryString.toString();}}/** * 获取ValueStack * * @return */public ValueStack getValueStack() {return ActionContext.getContext().getValueStack();}/** * 获取分页的List * * @param hql * @return */public PagingListHt getPagingListHt(String hql) {int pageNum = ((Integer) getValueStack().findValue("pageNum")).intValue();int pageSize = ((Integer) getValueStack().findValue("pageSize")).intValue();return new PagingListHt(ht, pageNum, pageSize, hql);}/** * 获取分页的List * * @param hql * @param clazz * @return */public PagingListHt getPagingListHt(String hql, Class clazz) {int pageNum = ((Integer) getValueStack().findValue("pageNum")).intValue();int pageSize = ((Integer) getValueStack().findValue("pageSize")).intValue();return new PagingListHt(ht, pageNum, pageSize, hql, clazz);}/** * 获取分页的List,预编译HQL语句 * * @param hql * @param parameters * @return */public PagingListHt getPagingListHt(String hql, Object[] parameters) {int pageNum = ((Integer) getValueStack().findValue("pageNum")).intValue();int pageSize = ((Integer) getValueStack().findValue("pageSize")).intValue();return new PagingListHt(ht, pageNum, pageSize, hql, parameters);}/** * 获取分页的List,预编译HQL语句 * * @param hql * @param parameters * @param clazz * @return */public PagingListHt getPagingListHt(String hql, Object[] parameters,Class clazz) {int pageNum = ((Integer) getValueStack().findValue("pageNum")).intValue();int pageSize = ((Integer) getValueStack().findValue("pageSize")).intValue();return new PagingListHt(ht, pageNum, pageSize, hql, parameters, clazz);}// 获取用户列表private static final String HQL_GET_ALL_USERS = "from User order by u.userId asc";public PagingListHt getAllUsers() {return getPagingListHt(HQL_GET_ALL_USERS);}private PagingListHt userList;public PagingListHt getUserList() {return userList;}/** * 用户列表*/public String userList() throws Exception {userList = getServMgr().getUserService().getAllUsers ();return "userList";}<div align="right"><@p.paging userList /></div>
<#list userList.list as news></#list>