在博客网站通常会有上百上千的文章,如果都拿出来显示就需要分页,由用户来翻看想要的页码。Hibernate查询支持分页查询,把数据库里的记录根据不同的页码展示。
按照面向对象的思想,首先可以定义一个页码的类,比如就叫做Page。这个类应该有几个属性:当前页码,下一页码,上一页码,每页显示记录数量,总页数。
package org.spring.model; public class Page { /** * 当前页码 */ private int pageNow; /** * 总页数 */ private int pageTotal; /** * 每页显示记录数量 */ private int pageSize; /** * 下一页码 */ private int nextPage; /** * 上一页码 */ private int prePage; }
这个类Page已经有了这些属性,全部是int整型,并且要生成这些属性的getter和setter方法。
在PersonDao.java接口类中定义一个新的方法getPersonPage,返回一个Page的对象。这个方法有两个参数int pageSize, int pageNow,也就是页面要由用户点击,把当前页码和每页显示多少记录数量传到这个方法。
public Page getPersonPage(int pageSize, int pageNow) throws Exception;
在PersonDaoSessionImpl.java中,实现这个接口的方法getPersonPage,同时生成Page的对象返回。
@Override public Page getPersonPage(int pageSize, int pageNow) throws Exception { Query query = sessionFactory.getCurrentSession().createQuery("from Person"); //HQL List personList = query.list(); Page page = new Page(); page.setPageSize(pageSize); page.setPageNow(pageNow); return page; }
这时的page对象里没有什么东西,还需要给page加一个属性用来存放查出来的记录,比如recordList,同时也需要生 成getter和setter方法。
/**
* 存放查询的记录
*/
private List recordList;
这样在page里就可以把查出来的记录放到page里。
page.setRecordList(personList);
现在查询出来的记录还是全部的数据记录,Hibernate的Query类有两个方法setFirstResult和setMaxResults,可以规定要查询的记录开始序号和此次要查询多少条记录。
query.setFirstResult(firstResult);
query.setMaxResults(maxResults);
这里的要查询多少条记录也就是pageSize,所以直接定义int maxResults = pageSize;
而要查询的记录开始序号就要计算下,公式为int firstResult = (pageNow-1) * pageSize;也就是当前页码减1之后乘以每页显示数量。可以推算下,比如每页显示10条记录,第1页要从(1-1)*10,即序号为0的记录开始。第2页要从(2-1)*10即序号为10的记录开始。注意这里的序号0,才是第一条记录,和数组或列表差不多,都是脚标从0开始。
Page还有一个属性要设置,记录总数量,比如定义为recordTotal。
/**
* 总记录数量
*/
private int recordTotal;
public int getRecordTotal() {
return recordTotal;
}
public void setRecordTotal(int recordTotal) {
this.recordTotal = recordTotal;
}
这就需要使用sql语句把此次查询的总数量也查询出来,可以定义一个局部方法getRecordTotal。
private int getRecordTotal() { Query query = sessionFactory.getCurrentSession().createQuery("select count(*) from Person"); List list = query.list(); Longtotal = (Long)list.get(0); return total.intValue(); }这个方法使用HQL语句select count(*) from Person查询出总记录数,这个查询结果虽然是一个list,但只有一个数量,可以把list的第一个结果强转为int返回就是总数量了。
int recordTotal = getRecordTotal();
page.setRecordTotal(recordTotal);
这样getPersonPage这个方法已经实现了。
@Override public Page getPersonPage(int pageSize, int pageNow) throws Exception { Query query = sessionFactory.getCurrentSession().createQuery("from Person"); //HQL int firstResult = (pageNow-1) * pageSize; int maxResults = pageSize; query.setFirstResult(firstResult); query.setMaxResults(maxResults); List personList = query.list(); Page page = new Page(); page.setPageSize(pageSize); page.setPageNow(pageNow); page.setRecordList(personList); int pageTotal = getRecordTotal(); page.setPageTotal(pageTotal); return page; }
在PersonService.java及PersonServiceImpl.java中也新增一个getPersonPage的方法和实现。
@Override public Page getPersonPage(int pageSize, int pageNow) throws Exception { return personDao.getPersonPage(pageSize, pageNow); }
PersonController.java中新增getPage方法,调用personService的getPersonPage可以把页码对象page传到jsp。
@RequestMapping(value = "/getPage", method = RequestMethod.GET) public Object getPage(HttpServletRequest request, HttpServletResponse response, PersonForm personForm) throws Exception { int pageSize = 10; int pageNow = personForm.getPageNow(); Page page = personService.getPersonPage(pageSize, pageNow); request.setAttribute("page", page); request.setAttribute("personList", page.getRecordList()); return "index"; }这里需要页面设定一个pageNow当前页,所以需要在PersonForm中加一个属性pageNow。
private int pageNow; public int getPageNow() { return pageNow; } public void setPageNow(int pageNow) { this.pageNow = pageNow; }
访问http://localhost:8080/springMvcMavenProject/getPage?pageNow=1可以看到页面已经把第一页显示出来了,再访问http://localhost:8080/springMvcMavenProject/getPage?pageNow=2,可以看到第二页的内容也正常。