之前在ITOO中也做过分页查询,但是当时没有总结,这次又遇到它,怎么可以放过它。。
分页查询除了离线查询之外,还有另一种方法,就是execute的方法。因为是三个表的联合查询,所以,就不能使用离线查询
一、实体类
*
* 一级分类的实体类对象
*/
public class Category implements Serializable {
private Integer cid;
private String cname;
//一级分类中存放二级分类的集合
private Set<CategorySecond> categorySeconds=new HashSet<CategorySecond>();
//get、set
}
/*
* 二级分类实体
*/
public class CategorySecond {
private Integer csid;
private String csname;
//所属一级分类,存的是一级分类的对象
private Category category;
//配置商品集合
private Set<Product> products=new HashSet<Product>();
//get、set
}
二、映射文件
1、一级分类
<hibernate-mapping>
<class name="cn.itcast.shop.category.vo.Category" table="category">
<id name="cid">
<generator class="native"/>
</id>
<property name="cname"/>
<!-- 配置二级分类的集合 order-by是按顺序排列 -->
<set order-by="csid" name="categorySeconds" lazy="false">
<key column="cid"/>
<one-to-many class="cn.itcast.shop.categorysecond.vo.CategorySecond"/>
</set>
</class>
</hibernate-mapping>
2、二级分类
<hibernate-mapping>
<class name="cn.itcast.shop.categorysecond.vo.CategorySecond" table="categorysecond">
<id name="csid">
<generator class="native"/>
</id>
<property name="csname"/>
<!-- 二级分类与一级分类的关联 lazy为延迟加载 -->
<many-to-one name="category" lazy="false" class="cn.itcast.shop.category.vo.Category" column="cid"></many-to-one>
<!-- 二级分类与商品的关联 -->
<set name="products">
<key column="csid"/>
<one-to-many class="cn.itcast.shop.product.vo.Product"/>
</set>
</class>
</hibernate-mapping>
三、分页设置类
//分页类的封装
package cn.itcast.shop.utils;
import java.util.List;
/*
* 分页类的封装
*/
public class PageBean<T> {
private int page;//当前页数
private int totalCount;//总记录数
private int totalPage;//总页数
private int limit;//每页显示的记录数
private List<T> list;//每页显示数据的集合
public int getPage() {
return page;
}
public void setPage(int page) {
this.page = page;
}
public int getTotalCount() {
return totalCount;
}
public void setTotalCount(int totalCount) {
this.totalCount = totalCount;
}
public int getTotalPage() {
return totalPage;
}
public void setTotalPage(int totalPage) {
this.totalPage = totalPage;
}
public int getLimit() {
return limit;
}
public void setLimit(int limit) {
this.limit = limit;
}
public List<T> getList() {
return list;
}
public void setList(List<T> list) {
this.list = list;
}
}
四、分页查询类
package cn.itcast.shop.utils;
import java.sql.SQLException;
import java.util.List;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.springframework.orm.hibernate3.HibernateCallback;
public class PageHibernateCallback<T> implements HibernateCallback<List<T>>{
private String hql;
private Object[] params;
private int startIndex;
private int pageSize;
public PageHibernateCallback(String hql, Object[] params,
int startIndex, int pageSize) {
super();
this.hql = hql;
this.params = params;
this.startIndex = startIndex;
this.pageSize = pageSize;
}
public List<T> doInHibernate(Session session) throws HibernateException,
SQLException {
//1
Query query = session.createQuery(hql);
//2
if(params != null){
for(int i = 0 ; i < params.length ; i ++){
query.setParameter(i, params[i]);
}
}
//
query.setFirstResult(startIndex);
query.setMaxResults(pageSize);
return query.list();
}
}
五、Action、Service、Dao
/*
* 商品的Action对象
*/
public class ProductAction extends ActionSupport implements ModelDriven<Product> {
//用于接收数据的模型驱动
private Product product=new Product();
public Product getModel() {
return product;
}
//注入商品的Service的方法
private ProductService productService;
public void setProductService(ProductService productService) {
this.productService = productService;
}
//接收分类cid
private Integer cid;
//接收二级分类的id
private Integer csid;
//注入一级分类的Service
private CategoryService categoryService;
//接收当前的页数
private int page;
//根据一级分类的id查询商品
public String findByCid(){
//List<Category> cList=categoryService.findAll();
PageBean<Product> pageBean=productService.findByPageCid(cid,page);//根据一级分类查询商品,分页查询
//将PageBean存入到值栈中
ActionContext.getContext().getValueStack().set("pageBean", pageBean);
return "findByCid";
}
}
/*
* 商品的业务层代码
*/
@Transactional
public class ProductService {
//注入ProductDao
private ProductDao productDao;
public void setProductDao(ProductDao productDao) {
this.productDao = productDao;
}
//根据一级分类的cid带有分页查询商品
public PageBean<Product> findByPageCid(Integer cid, int page) {
PageBean<Product> pageBean=new PageBean<Product>();
//设置当前页数
pageBean.setPage(page);
//设置每页显示记录数
int limit=8;
pageBean.setLimit(limit);
//设置总记录数
int totalCount=0;
totalCount=productDao.findCountCid(cid);
pageBean.setTotalCount(totalCount);
//设置总页数
int totalPage=0;
//Math.ceil(totalCount / limit);
if(totalCount % limit==0){
totalPage=totalCount/limit;
}else{
totalPage=totalCount/limit + 1;
}
pageBean.setTotalPage(totalPage);
//每页显示的数据集合
//从哪开始
int begin=(page-1)*limit;
List<Product> list=productDao.findByPageCid(cid,begin,limit);
pageBean.setList(list);
return pageBean;
}
}
/*
* 商品的持久层代码
*/
public class ProductDao extends HibernateDaoSupport{
//根据分类id查询商品的个数
public int findCountCid(Integer cid) {
String hql="select count(*) from Product p where p.categorySecond.category.cid=?";
List<Long> list=this.getHibernateTemplate().find(hql,cid);
if(list != null && list.size()>0){
return list.get(0).intValue();
}
return 0;
}
//根据一级分类id查询商品的集合
//用hql查询就不能使用离线查询
public List<Product> findByPageCid(Integer cid, int begin, int limit) {
String hql="select p from Product p join p.categorySecond cs join cs.category c where c.cid=?";
//分页另一种写法
List<Product> list=this.getHibernateTemplate().execute(new PageHibernateCallback<Product>(hql,new Object[]{cid},begin,limit));
if(list != null && list.size()>0){
return list;
}
return null;
}
}
六、JSP
<div class="pagination">
<span>第 <s:property value="pageBean.page"/>/<s:property value="pageBean.totalPage"/> 页</span>
<s:if test="cid != null">
<s:if test="pageBean.page != 1">
<a href="${ pageContext.request.contextPath }/product_findByCid.action?cid=<s:property value="cid"/>&page=1" class="firstPage"> </a>
<a href="${ pageContext.request.contextPath }/product_findByCid.action?cid=<s:property value="cid"/>&page=<s:property value="pageBean.page-1"/>" class="previousPage"> </a>
</s:if>
<s:iterator var="i" begin="1" end="pageBean.totalPage">
<s:if test="pageBean.page != #i">
<a href="${ pageContext.request.contextPath }/product_findByCid.action?cid=<s:property value="cid"/>&page=<s:property value="#i"/>"><s:property value="#i"/></a>
</s:if>
<s:else>
<span class="currentPage"><s:property value="#i"/></span>
</s:else>
</s:iterator>
<s:if test="pageBean.page != pageBean.totalPage">
<a class="nextPage" href="${ pageContext.request.contextPath }/product_findByCid.action?cid=<s:property value="cid"/>&page=<s:property value="pageBean.page+1"/>"> </a>
<a class="lastPage" href="${ pageContext.request.contextPath }/product_findByCid.action?cid=<s:property value="cid"/>&page=<s:property value="pageBean.totalPage"/>"> </a>
</s:if>
</s:if>
<s:if test="csid != null">
<s:if test="pageBean.page != 1">
<a href="${ pageContext.request.contextPath }/product_findByCsid.action?csid=<s:property value="csid"/>&page=1" class="firstPage"> </a>
<a href="${ pageContext.request.contextPath }/product_findByCsid.action?csid=<s:property value="csid"/>&page=<s:property value="pageBean.page-1"/>" class="previousPage"> </a>
</s:if>
<s:iterator var="i" begin="1" end="pageBean.totalPage">
<s:if test="pageBean.page != #i">
<a href="${ pageContext.request.contextPath }/product_findByCsid.action?csid=<s:property value="csid"/>&page=<s:property value="#i"/>"><s:property value="#i"/></a>
</s:if>
<s:else>
<span class="currentPage"><s:property value="#i"/></span>
</s:else>
</s:iterator>
<s:if test="pageBean.page != pageBean.totalPage">
<a class="nextPage" href="${ pageContext.request.contextPath }/product_findByCsid.action?csid=<s:property value="csid"/>&page=<s:property value="pageBean.page+1"/>"> </a>
<a class="lastPage" href="${ pageContext.request.contextPath }/product_findByCsid.action?csid=<s:property value="csid"/>&page=<s:property value="pageBean.totalPage"/>"> </a>
</s:if>
</s:if>
</div>
总结
这是一个很好的多关联分页查询的模板