Hibernate分页查询与泛型

本文介绍了一种基于Java和Hibernate的分页查询实现方法,包括自定义Page类用于计算分页数据,WebPage类用于在JSP页面展示分页导航,以及HibernateUtil类中的两种分页查询方式。

JE有两篇文章,关于分页查询泛型 的,写的很好.这里收藏一下.

Hibernate分页查询小结

JDK5.0后的泛型程序设计

---------------------------------------------

下面是我自己写的分页方法,同时也参考了上面两篇文章.

以下代码用在了实际的项目中.

Page类,计算分页数据

package common.dao;

/**
 * 分页功能
 */
public class Page
{
	public final int	DEFAULT_PAGESIZE	= 15;	// 每页记录数

	public final int	DEFAULT_PAGE		= 1;	// 默认显示第几页

	// =========================================================================================

	protected int		count;						// 总的记录数

	protected int		pageSize;					// 每页记录数

	protected int		pageCount;					// 总的页数

	protected int		page;						// 本页页号

	protected int		start;						// 起始记录下标(MySql从0开始)

	// =========================================================================================
	/**
	 * 构造方法
	 * 
	 * @param nPageSize
	 *            每页记录数
	 * @param nPage
	 *            本页页号
	 */
	public Page(final int nPageSize, final int nPage)
	{
		pageSize = nPageSize; // 每页大小
		page = nPage; // 本页页号
	}

	/**
	 * 构造方法 ,默认每页20条记录
	 * 
	 * @param nPage
	 *            本页页号
	 */
	public Page(final int nPage)
	{
		pageSize = DEFAULT_PAGESIZE; // 每页大小
		page = nPage; // 本页页号
	}

	/**
	 * 构造方法 ,默认每页20条记录,显示第一页
	 * 
	 */
	public Page()
	{
		pageSize = DEFAULT_PAGESIZE; // 每页大小
		page = DEFAULT_PAGE; // 本页页号
	}

	/**
	 * 分页初始化
	 * 
	 * @param nCount
	 *            总的记录数
	 */
	public void init(final int nCount)
	{
		init(nCount, pageSize, page);
	}

	/**
	 * 分页初始化;记录总记录数,每页记录数,当前页,并计算总页数、本页大小和检测当前页是否有效
	 * 
	 * @param nCount
	 *            总的记录数
	 * @param nPageSize
	 *            每页记录数
	 * @param nPage
	 *            本页页号
	 */
	public void init(final int nCount, final int nPageSize, final int nPage)
	{
		count = nCount; // 总的项数
		page = nPage; // 本页页号
		pageSize = nPageSize; // 每页大小
		if (0 >= pageSize)
		{
			pageSize = DEFAULT_PAGESIZE;
		}
		pageCount = (nCount + pageSize - 1) / pageSize; // 计算总的页数

		// 防止 Page 超范围并计算当前页大小
		if (page > pageCount)
		{
			page = pageCount;
		}
		if (page < 1)
		{
			page = DEFAULT_PAGE;
		}

		start = min();
	}

	/**
	 * 计算起始记录下标(MySql从0开始)
	 * 
	 * @return
	 */
	public int min()
	{
		final int max = page * pageSize - 1;
		return max - pageSize + 1;
	}

	//	public int max()
	//	{
	//		final int max = page * pageSize - 1;
	//		return max;
	//	}

	/**
	 * 计算导航页(开始页号)
	 * 
	 * @param nPageNav
	 *            导航页数
	 * @return 开始页号
	 */
	public final int CalcMinPage(final int nPageNav)
	{
		int min = page - (nPageNav / 2);
		int max = page + (nPageNav / 2);
		if (min < 1)
		{
			final int a = 0 - min;
			min = 1;
			max = max + a;
		}
		if (max > pageCount)
		{
			final int b = max - pageCount;
			max = pageCount;
			min = min - b < 1 ? 1 : min - b;
		}
		return min;
	}

	/**
	 * 计算导航页(结束页号)
	 * 
	 * @param nPageNav
	 *            导航页数
	 * @return 结束页号
	 */
	public final int CalcMaxPage(final int nPageNav)
	{
		int min = page - (nPageNav / 2);
		int max = page + (nPageNav / 2);
		if (min < 1)
		{
			final int a = 0 - min;
			min = 1;
			max = max + a;
		}
		if (max > pageCount)
		{
			final int b = max - pageCount;
			max = pageCount;
			min = min - b < 1 ? 1 : min - b;
		}
		return max;
	}

	@Override
	public String toString()
	{
		final StringBuffer sbf = new StringBuffer();
		sbf.append(" 总的记录数:" + count);
		sbf.append(" 每页记录数:" + pageSize);
		sbf.append(" 总的页数:" + pageCount);
		sbf.append(" 本页页号:" + page);
		sbf.append(" 起始记录下标:" + start);
		return sbf.toString();
	}

	public int getCount()
	{
		return count;
	}

	public void setCount(final int count)
	{
		this.count = count;
	}

	public int getPageSize()
	{
		return pageSize;
	}

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

	public int getPageCount()
	{
		return pageCount;
	}

	public void setPageCount(final int pageCount)
	{
		this.pageCount = pageCount;
	}

	public int getPage()
	{
		return page;
	}

	public void setPage(final int page)
	{
		this.page = page;
	}

	public int getStart()
	{
		return start;
	}

	public void setStart(final int start)
	{
		this.start = start;
	}

}

WebPage (继承自Page) 扩展了在JSP页面上显示 "上一页 1 2 3 下一页" 的功能

package common.web;

import javax.servlet.http.HttpServletRequest;

import org.apache.struts2.ServletActionContext;

import common.dao.Page;

public class WebPage extends Page
{
	public final int	DEFAULT_NAV_SIZE	= 20;			// 导航页数

	private boolean		center				= true;		//默认居中

	private String		className			= "page_css";	//默认CSS

	/**
	 * 构造方法
	 * 
	 * @param nPageSize
	 *            每页记录数
	 * @param nPage
	 *            本页页号
	 */
	public WebPage(final int nPageSize, final int nPage, final String sPageURLParas)
	{
		super(nPageSize, nPage);
		setPageURL(sPageURLParas);
	}

	/**
	 * 构造方法
	 * 
	 * @param nPageSize
	 *            每页记录数
	 * @param nPage
	 *            本页页号
	 */
	public WebPage(final int nPageSize, final int nPage)
	{
		super(nPageSize, nPage);
		setPageURL("");
	}

	/**
	 * 构造方法 ,默认每页20条记录
	 * 
	 * @param nPage
	 *            本页页号
	 */
	public WebPage(final int nPage)
	{
		super(nPage);
		setPageURL("");
	}

	private String	pageURL;	// 导航地址

	private String	pageNAV;	// 导航表格

	public void setPageURL(final String sPageURLPara)
	{
		//final HttpServletRequest request,
		final HttpServletRequest request = ServletActionContext.getRequest();
		if (sPageURLPara.length() > 0)
		{
			pageURL = "?" + sPageURLPara.substring(1) + "&";
		}
		else
		{
			pageURL = "?";
		}
		pageURL = request.getRequestURI() + pageURL + "page=";
		pageNAV = null;
	}

	public String getPageNAV()
	{
		final int nPageNav = DEFAULT_NAV_SIZE; // 导航页数	
		final int nPage = page; // 当前页号
		final int nPageMin = CalcMinPage(nPageNav); // 开始页号
		final int nPageMax = CalcMaxPage(nPageNav); // 结束页号
		final StringBuffer sPageNav = new StringBuffer(1024);
		if (nPageMin < nPageMax)
		{

			sPageNav.append("<table class=\"" + className + "\"");
			if (center)
			{
				//导航条居中 ,样式表
				sPageNav.append(" align=\"center\">");
			}
			sPageNav.append("<tr>\r\n");
			if (nPageMin != nPage)
			{

				sPageNav.append("<td><a href=\"");
				sPageNav.append(pageURL + (nPage - 1));
				sPageNav.append("\">上页</a></td>\r\n");
			}
			else
			{
				sPageNav.append("<td>上页</td>\r\n");
			}
			for (int i = nPageMin; i <= nPageMax; i++)
			{
				sPageNav.append("<td>");
				if (i != nPage)
				{
					sPageNav.append("<a style='text-decoration: underline' href=\"");
					sPageNav.append(pageURL + (i));
					sPageNav.append("\">");
				}
				if (i != nPage)
				{
					sPageNav.append(i);
				}
				else
				{
					sPageNav.append("<b style='color:#ff7700'>" + (i) + "</b>");
				}
				if (i != nPage)
				{
					sPageNav.append("</a>");
				}
				sPageNav.append("</td>\r\n");
			}

			if (nPageMax != nPage)
			{

				sPageNav.append("<td><a style='text-decoration: underline' href=\"");
				sPageNav.append(pageURL + (page + 1));
				sPageNav.append("\">下页</a></td>\r\n");
			}
			else
			{
				sPageNav.append("<td>下页</td>\r\n");
			}
			sPageNav.append("</tr></table>\r\n");
		}
		pageNAV = sPageNav.toString();
		return pageNAV;
	}

	public boolean isCenter()
	{
		return center;
	}

	public void setCenter(final boolean center)
	{
		this.center = center;
	}

	public String getClassName()
	{
		return className;
	}

	public void setClassName(final String className)
	{
		this.className = className;
	}
}

HibernateUtil 类,有两种分页方法

package pic.dao;

import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.Projections;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import org.springframework.stereotype.Repository;

import common.dao.Page;

@Repository
public class HibernateUtil extends HibernateDaoSupport
{

	/**
	 * 注入sessionFactory
	 * 
	 * @param sessionFactory
	 */
	@Resource(name = "sessionFactory")
	public void setFactory(final SessionFactory sessionFactory)
	{
		//HibernateDaoSupport上的方法,注入sessionFactory
		setSessionFactory(sessionFactory);
	}

	/**
	 * 取得当前session
	 * 
	 * @return
	 */
	public Session getCS()
	{
		return this.getSession();
		//return this.getSessionFactory().getCurrentSession();
	}

	/**
	 * HQL分页查询
	 * 
	 * @param page
	 *            分页对象,包含分页信息,如每页记录数,当前页码等
	 * @patam patam 参数集合 HQL如下:from User where expertname like :expertname
	 *        map.put("expertname", "%" + expertName + "%");
	 *        expertname是HQL中的:expertname
	 * 
	 * @param hqlCount
	 *            计算总记录数的sql
	 * @param hql
	 *            查询的Sql
	 * @return List 结果集合
	 */
	@SuppressWarnings("unchecked")
	public List findListPage(final Page page, final Map param, final String hqlCount, final String hql)
	{
		final Session session = this.getCS();
		//查询总记录条数的Query
		final Query query_count = session.createQuery(hqlCount);

		//查询的Query
		final Query query = session.createQuery(hql);
		if (param != null)
		{
			//query.setProperties(param);
			final Iterator it = param.keySet().iterator();
			while (it.hasNext())
			{
				final Object key = it.next();
				//两个Query查询条件相同
				query_count.setParameter(key.toString(), param.get(key));
				query.setParameter(key.toString(), param.get(key));
			}
		}
		//总记录数
		final int nCount = ((Long) query_count.iterate().next()).intValue();
		//计算分页数据
		page.init(nCount);
		//从第N条开始 
		query.setFirstResult(page.getStart());
		//取出X条
		query.setMaxResults(page.getPageSize());
		final List list = query.list();
		return list;
	}

	/**
	 * Criteria 分页查询, 要事先设置好查询条件, 再把Criteria对象传进来
	 * 
	 * @param page
	 *            分页对象
	 * @param criteria
	 *            Criteria对象,要事先设置好查询条件, 再把Criteria对象传进来 ,
	 *            如criteria.add(Restrictions.eq("name", "zl"))
	 * 
	 * @return 结果集合
	 */
	@SuppressWarnings("unchecked")
	public List findListPage(final Page page, final Criteria criteria)
	{
		// 获取根据条件分页查询的总行数  
		final int rowCount = (Integer) criteria.setProjection(Projections.rowCount()).uniqueResult();
		criteria.setProjection(null);
		//计算分页数据
		page.init(rowCount);
		criteria.setFirstResult(page.getStart());
		criteria.setMaxResults(page.getPageSize());
		return criteria.list();
	}

}

JUnit测试类

package junit_test.pic.dao;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import junit_test.base.JUnitBase_svc;

import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.criterion.Restrictions;
import org.junit.BeforeClass;
import org.junit.Test;

import pic.dao.HibernateUtil;
import pic.dao.entity.Email;
import pic.svc.EmailManager;

import common.dao.Page;

/**
 * 测试HibernateUtil 基类
 * 
 * @author zl
 * 
 */
public class HibernateUtilTest extends JUnitBase_svc
{
	static HibernateUtil	hibernateUtil;

	@BeforeClass
	public static void setUpBeforeClass() throws Exception
	{
		hibernateUtil = (HibernateUtil) getBean("hibernateUtil");
	}

	/**
	 * 测试取得hibernateUtil bean
	 */
	@Test
	public void testGetHibernateUtil()
	{
		assertNotNull(hibernateUtil);
	}

	@Test
	public void add()
	{
		//先添加一些邮件
		for (int i = 0; i < 7; i++)
		{
			final Email email = new Email();
			email.setContent("内容2");
			email.setIndex(2);
			email.setQueueName("队列名称2");
			email.setReceivers("Receivers2");
			email.setSubject("Subject2");
			email.setSum(20);
			final EmailManager emailManagerImpl = (EmailManager) getBean("emailManagerImpl");
			emailManagerImpl.add(email);
		}
	}

	/**
	 * 测试分页方法
	 */
	@SuppressWarnings("unchecked")
	@Test
	public void testFindListPage()
	{

		//分页测试 , 第一页
		final String where = " where content=:content ";
		final String hqlCount = "select count(*) from Email" + where;
		final String hql = "from Email" + where;

		final Map<String, Object> param = new HashMap<String, Object>();
		param.put("content", "内容2");

		final List<Email> list = hibernateUtil.findListPage(new Page(), param, hqlCount, hql);
		for (final Email e : list)
		{
			System.out.println(e.toString());
		}

		//测试 超出总页数
		hibernateUtil.findListPage(new Page(10000), param, hqlCount, hql);

		//测试 当前页码小于0
		hibernateUtil.findListPage(new Page(-1), param, hqlCount, hql);
	}

	/**
	 * 测试分页方法
	 */
	@Test
	public void testFindListPage2()
	{
		final Session session = getNewS();
		final Criteria criteria = session.createCriteria(Email.class);
		criteria.add(Restrictions.eq("content", "内容2"));
		//criteria.add(Restrictions.like(propertyName, value))
		final List<Email> list = hibernateUtil.findListPage(new Page(2), criteria);
		for (final Email e : list)
		{
			System.out.println(e.toString());
		}
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值