6、实现通用分页功能二(实现通用分页查询的业务方法)

【6、实现通用分页功能二(实现通用分页查询的业务方法)】基本思路:
当一个用户提交的分页查询请求过来时,通常带有请求的页码、过滤条件、排序要求等信息。我们可以在控制层,即在action类相应方法中,把上面的请求信息封闭成一个HQL语句,然后传给业务层的分页查询方法,由分页查询方法返回一个Page对象,这个对象里面就包括了需要在页面中显示的所有内容。
在业务层的分页查询方法中,为了封装一个Page对象,需要查询符合条件的总记录数和当前页的记录,所以在控制层中需要生成两条HQL语句,并且还要传相关的HQL语句参数过来。针对这个需求,我们可以创建一个工具类HqlHelper来负责生成这些HQL语句。
考虑到通用性,我们可以将分页查询方法放在BaseDao接口中。
一、创建HqlHelper工具类

package com.charlie.shop.util; import java.util.ArrayList; import java.util.List; /** * 这个类负责拼接分页查询的hql语句 * @author charlie * */ public class HqlHelper { /**查询数据列hql语句**/ private String listHql; /**查询符合条件的总记录数的HQL语句**/ private String countHql; /**HQL语句的参数数组**/ private List parameters = new ArrayList(); /**条件子句,用于过滤,非必需,所以要初始化为空**/ private String conditionString = ""; /**排序子句,非必需,先初始化为空**/ private String orderString =""; /**要查询的实体类的类名**/ private String className; /**要查询的实体类的别名**/ private String alias; /** * 构造器 * 有些实体的删除操作并不是物理删除,而只是设置一个visible属性,删除时将该属性设为false,即不可见 * 那么,可以增加一个约定,那就是如果删除时并不想真正物理删除的实体,都给它加上一个visible属性, * 而在删除时是真正物理删除的实体则不能有这个visible属性 * 如果设置了visible属性,那么在显示列表时,也必须不能显示那些visible=false的对象 * 为了保证这点,可以在HqlHelper构造器中加了一个布尔标志flag * 当flag=true时,要查询的实体具有visible属性,那么要加上过滤条件 * 当flag=false时,则不用加过滤条件 * @param className实体类类名 * @param alias实体类的别名 * @param flag标志,true时表示实体具有visible属性,false表不具有 */ public HqlHelper(String className,String alias,boolean flag){ this.className = className; this.alias = alias; listHql = "FROM "+className+" "+alias+" "; //注意空格 countHql = "SELECT COUNT(*) FROM "+className+" "+alias+" "; //如果实体具有visible属性,那么查询的条件必须有visible=true if(flag){ this.setCondition(alias+".visible=?", true); } } /** * 设置过滤子句 * @return 返回对象本身,可以实现链式方法调用 */ public HqlHelper setCondition(String condition,Object...params){ if(conditionString.length()==0){ //条件子句第一次赋值 conditionString=" WHERE "+condition; }else{ //不是第一次 conditionString +=" AND "+condition; } //添加参数对象 for(int i=0; i getParameters() { return parameters; } public void setParameters(List parameters) { this.parameters = parameters; } public String getConditionString() { return conditionString; } public void setConditionString(String conditionString) { this.conditionString = conditionString; } public String getOrderString() { return orderString; } public void setOrderString(String orderString) { this.orderString = orderString; } public String getClassName() { return className; } public void setClassName(String className) { this.className = className; } public String getAlias() { return alias; } public void setAlias(String alias) { this.alias = alias; } public String getCountHql() { countHql += " "+conditionString; return countHql; } public void setCountHql(String countHql) { this.countHql = countHql; } }




二、BaseDao接口中添加分页查询方法

/** * 分页查询方法 */ public Page getByPage(int pageNow,HqlHelper hqlHelper);


三、在BaseDaoImp类中实现分页查询方法
分三步实现:
1、查询符合条件的总记录数
2、查询符合条件的数据
3、封装到Page对象中,并返回

// 在分页查询中,每一页显示的记录数,默认是10 protected int pageSize = 10;


@Override public Page getByPage(int pageNow, HqlHelper hqlHelper) { int maxResults = pageSize; int firstResult = (pageNow-1)*pageSize; int recordCount = getRecordCount(hqlHelper.getCountHql(),hqlHelper.getParameters()); List recordList = getPageData(hqlHelper.getListHql(), hqlHelper.getParameters(), firstResult, maxResults); Page page = new Page(pageNow, pageSize, recordCount, recordList); return page; } /** * 查询符合条件的总记录数 */ private int getRecordCount(String countHql,List params){ Query query = getSession().createQuery(countHql); for(int i=0; i getPageData(String hql,List params,int firstResult,int maxResults) { Query query = getSession().createQuery(hql); for(int i=0; i


    推荐阅读