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<Object> parameters = new ArrayList<Object>();
	/**条件子句,用于过滤,非必需,所以要初始化为空**/
	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<params.length;i++){
			parameters.add(params[i]);
		}
		return this;
	}
	/**
	 * 设置排序子句
	 * @param order 字段名
	 * @param flag  升降序标志,true表升序,false表降序
	 * @return 返回对象自己,可以实现链式方法调用
	 */
	public HqlHelper setOrder(String order,boolean flag){
		if(orderString.length()==0){
			//第一次
			orderString = " ORDER BY "+order;
		}else{
			//不是第一次
			orderString += " , "+order;
		}
		//添加排序方式
		if(flag){
			//为true,表升序
			orderString += " ASC ";
		}else{
			//降序
			orderString += " DESC ";
		}
		return this;
	}
	
	//--------------getter/setter方法----------------------
	public String getListHql() {
		listHql += " "+conditionString+" "+orderString;
		return listHql;
	}

	public void setListHql(String hql) {
		this.listHql = hql;
	}

	public List<Object> getParameters() {
		return parameters;
	}

	public void setParameters(List<Object> 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<T> getByPage(int pageNow,HqlHelper hqlHelper);

三、在BaseDaoImp类中实现分页查询方法

分三步实现:

1、查询符合条件的总记录数

2、查询符合条件的数据

3、封装到Page对象中,并返回

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

        @Override
	public Page<T> getByPage(int pageNow, HqlHelper hqlHelper) {
		int maxResults = pageSize;
		int firstResult = (pageNow-1)*pageSize;
		int recordCount = getRecordCount(hqlHelper.getCountHql(),hqlHelper.getParameters());
		List<T> recordList = getPageData(hqlHelper.getListHql(), hqlHelper.getParameters(), firstResult, maxResults);
		Page<T> page = new Page<T>(pageNow, pageSize, recordCount, recordList);
		return page;
	}
	/**
	 * 查询符合条件的总记录数
	 */
	private int getRecordCount(String countHql,List<Object> params){
		Query query = getSession().createQuery(countHql);
		for(int i=0;i<params.size();i++){
			query.setParameter(i,params.get(i));
		}
		return Integer.parseInt(query.uniqueResult().toString());
	}
	/**
	 * 查询分页数据
	 */
	private List<T> getPageData(String hql,List<Object> params,int firstResult,int maxResults) {
		Query query = getSession().createQuery(hql);
		for(int i=0;i<params.size();i++){
			query.setParameter(i,params.get(i));
		}
		query.setFirstResult(firstResult);
		query.setMaxResults(maxResults);
		return query.list();
	}
	

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值