学过Hibernate的程序员都知道,在Hibernate中为用户准备好了分页数据库的功能。也就是两句话:
query.setFirstResult(pageStartRow);
query.setMaxResults(pageSize);
最近开始学Hibernate就写了一个分页的功能,很实用,实现了跳转到相应的页:GO,和用户可选的页面显示数据的数量,与大家分享下,如果有不正确的地方请大家多多指出。谢谢,就不多说废话了.....
首先我们准备一个 Pager.java
package com.rao.entitys; import java.util.concurrent.CountDownLatch; public class Pager { private int currentPage; //当前页 private int totalRows; //总行数 private int pageSartRow; //每页开始的数据行 private int totalpages; //总页数 private int pageSize; //每页 显示的数据行数量 public int getCurrentPage() { return currentPage; } public void setCurrentPage(int currentPage) { this.currentPage = currentPage; } public int getTotalRows() { return totalRows; } public void setTotalRows(int totalRows) { this.totalRows = totalRows; } public int getPageSartRow() { return pageSartRow; } public void setPageSartRow(int pageSartRow) { this.pageSartRow = pageSartRow; } public int getTotalpages() { return totalpages; } public void setTotalpages(int totalpages) { this.totalpages = totalpages; } public int getPageSize() { return pageSize; } public void setPageSize(int pageSize) { this.pageSize = pageSize; } /* * 构造方法,初始化数据 */ public Pager(int totals,int size){ this.totalRows = totals; this.pageSize = size; //计算总页数, if (totalRows%pageSize!=0) { this.totalpages = totalRows/pageSize+1; }else { this.totalpages = totalRows/pageSize; } //默认当前页为第一页 this.currentPage = 1; //默认数据的开始为0 this.pageSartRow = 0; } /** * 上一页 */ public void previousPage(){ //如果当前页小于等于1,返回 if (currentPage<=1) { return; } //当前页减一页 currentPage--; //设置每页开始的数据行 pageSartRow = (currentPage-1)*pageSize; } /** * 下一页 */ public void nextPage(){ //如果当前页大于总页数,设置当前页为最后一页 if (currentPage>=totalpages) { currentPage=totalpages; }else { //否则当前页加一页 currentPage++; } pageSartRow = (currentPage-1)*pageSize; } /** * 首页 */ public void firsPage(){ currentPage=1; pageSartRow = (currentPage-1)*pageSize; } /** * 尾页 */ public void lastPage(){ currentPage = totalpages; pageSartRow = (currentPage-1)*pageSize; } /** * Go */ public void goPage(int go){ //当前页等于用户输入跳转的那一页 currentPage = go; //如果用户输入的大于总页数,go to last page if (currentPage>=totalpages) { currentPage=totalpages; }else if(currentPage<=1){ //if input <= 1, go to first page currentPage=1; } pageSartRow = (currentPage-1)*pageSize; } /** * 设置页面显示的数据条数 * @param show 数据条数 */ public void showcount(int show){ setPageSize(show); } }
然后我们需要一个工具类,用于获得一个Pger对象,在Action中使用:
PagerUtil.java
package com.rao.util; import javax.servlet.http.HttpServletRequest; import org.hibernate.Hibernate; import com.rao.entitys.Pager; /** * @author raozhiyong 用于得到一个Pager的实例 */ public class PagerUtil { public static Pager getPager(HttpServletRequest request, int totalRows) { //得到页面传入的pagesize参数,也就是用户选中的值 String pageSizesString = request.getParameter("showcount"); int pageSize; //如果这个参数为空的话,说明是第一次浏览,初始化页面默认的pagesize 为五条数据 if (pageSizesString==null) { pageSize = 5; }else { //否则讲pageSize属性设置为用户选择的大小 pageSize = new Integer(pageSizesString); } //根据数据库中的数据总数和每页显示的pagesize,创建一个初始化的Pager对象 Pager pager = new Pager(totalRows,pageSize); // 得到页面传输近来的当前页 String current = request.getParameter("current"); // 如果传入的参数为空,则访问首页,默认当前页为第一页 // 如果不为空就重新设置当前页面的值 if (current != null) { pager.setCurrentPage(new Integer(current)); } // 得到用户请求操作,首页,尾页,上一页,下一页 String pagedo = request.getParameter("pagedo"); if (pagedo != null) { if ("first".equalsIgnoreCase(pagedo)) { pager.firsPage(); } else if ("last".equalsIgnoreCase(pagedo)) { pager.lastPage(); } else if ("previous".equalsIgnoreCase(pagedo)) { pager.previousPage(); } else if ("next".equalsIgnoreCase(pagedo)) { pager.nextPage(); } else if ("go".equalsIgnoreCase(pagedo)) { //接受用户输入的跳转页 String gocount = request.getParameter("gocount"); // 初始化为回到第一页(也许用户输入的数据合法,那么这时候我们应当默认回到第一页) int go = 1; try { go = new Integer(gocount); } catch (Exception e) { e.printStackTrace(); } pager.goPage(go); } else if ("select".equalsIgnoreCase(pagedo)) { String showcount = request.getParameter("showcount"); // 初始化为每页5条数据 int size = 5; try { size = new Integer(showcount); } catch (Exception e) { e.printStackTrace(); } pager.showcount(size); } } return pager; } }
Struts中Action的代码如下:
public ActionForward all(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) { System.out.println("=========all========"); String uriString = null; try { // 得到数据的总条数 int totalRows = studentDao.totalCount(); //获得一个Pager对象 Pager pager = PagerUtil.getPager(request, totalRows); //取出相应的数据 List stulist = studentDao.selectStudentList(pager.getPageSartRow(),pager.getPageSize()); //将pager对象共享的request作用范围中,以便页面使用 request.setAttribute("pager", pager); //将查询到的List共享的request作用范围中,以便页面使用 request.setAttribute("stulist", stulist); uriString = "list"; } catch (Exception e) { uriString = "error"; e.printStackTrace(); } return mapping.findForward(uriString); }
以上的Action使用了Hibernate中的两个方法:
1.totalCount():得到总数据量;
2.selectStudentList(pager.getPageSartRow(),pager.getPageSize()); 得到请求的List
Hibernate范围中的代码如下:
/** * 查询所有学生信息 */ public List selectStudentList(int pageStartRow,int pageSize) { List list = new ArrayList(); try { session = HibernateSessionFactory.getSession(); final String hql = "from Student"; Query query = session.createQuery(hql); query.setFirstResult(pageStartRow); query.setMaxResults(pageSize); list = query.list(); Hibernate.initialize(list); } catch (HibernateException e) { if (transaction!=null) { transaction.rollback(); } e.printStackTrace(); } finally { //session.close(); } return list; } public int totalCount() { int count = 0; try { session = HibernateSessionFactory.getSession(); //HQL Queqy final String hql = "select count(*) from Student"; Query query = session.createQuery(hql); //count = ((Number)query.uniqueResult()).intValue(); count = ((Number)query.iterate().next()).intValue(); //QBC Query /*Criteria criteria = session.createCriteria(Student.class); ProjectionList pList = Projections.projectionList(); pList.add(Projections.rowCount()); criteria.setProjection(pList); count = ((Number)criteria.uniqueResult()).intValue();*/ } catch (HibernateException e) { if (transaction!=null) { transaction.rollback(); } e.printStackTrace(); } finally { session.close(); } return count; }
最后我们来看看前台代码:
<%@ page language="java" pageEncoding="gbk"%> <%@ taglib uri="http://struts.apache.org/tags-bean" prefix="bean"%> <%@ taglib uri="http://struts.apache.org/tags-html" prefix="html"%> <%@ taglib uri="http://struts.apache.org/tags-logic" prefix="logic"%> <%@ taglib uri="http://struts.apache.org/tags-tiles" prefix="tiles"%> 学生信息管理
新增学生信息
编号 姓名 年龄
地址 班级 操作
共有 首页 上一页 下一页 尾页 =48&&event.keyCode<=57||event.keyCode==46" οnpaste="return !clipboardData.getData('text').match(/\D/)" οndragenter="return false" style="ime-mode: Disabled" /> GO 每页显示 条数据
从jsp页面上可以看到,我把分页模拟成了一个组件化的用例,放在一个table中,我们可以在任何一个项目中使用它,只要能将代码复制即可,当然还要修改下请求的路径,这个就要以项目为中心了,这里的请求我大多是用的javasript,因为我们必须在没有表单的情况下获得用户的输入和选择,所以我选择了JavaScript,当然还有很多方法,大家有兴趣可以去研究。由于我在代码中注释都写得很清楚,所以我在这里只是讲下其中一个路径问题:stutent.do?dowhat=all&pagedo=next¤t=${pager.currentPage}&showcount=" + count
dowhat : 这是Action的请求,我用的是DispatchAction,这里指的是Action的请求参数;
current :当前页,从request中获得;
showcount: 用户选择的当前显示多少行数据,也就是pager的pageSize;
gocount : 用户输入的转到第几个的数值;
在贴出学习时对分页的分析图片吧:
http://b31.photo.store.qq.com/http_imgload.cgi?/rurl4_b=25b845d29607d32ca11c8a09617bf58b9889eb6d2c485aacff502cc045c39bc12e64069bea3681c5d7142e01c1ce54705b0698c740fe83c34a8bc4fef145d592f04a7df7e340263f8e4c7ae787515f321b1f26dc&a=25&b=31
还有本例的图样,大家可以先睹为快:
http://b31.photo.store.qq.com/http_imgload.cgi?/rurl4_b=25b845d29607d32ca11c8a09617bf58b1b7471265f322d130cd674d75cc0fb024fff79b1394f042be3cc3104c3c82414dfac42b6a8edc705f556ff996e15d4f4d10233e3b90edcd1c1ffd94321af0177191a7b35&a=31&b=31
就是这么多,希望对大家有所帮助!