20190509(已解决)关于QueryHelper的使用介绍

QueryHelper.java 的代码如下:

package com.ninebot.ad.util;

import java.util.ArrayList;
import java.util.List;

import com.ninebot.ad.core.Dao.BaseDao;
import com.ninebot.ad.page.PageResult;
import com.opensymphony.xwork2.ActionContext;

public class QueryHelper {
	//from子句
	private String fromClause=""; // FROM子句
	//where子句
	private String whereClause = ""; // Where子句
	//order by子句
	private String orderByClause = ""; // OrderBy子句

	private List<Object> parameters = new ArrayList<Object>(); // 参数列表

	//排序顺序
	public static String ORDER_BY_DESC = "DESC";//降序
	public static String ORDER_BY_ASC = "ASC";//升序
	/**
	 * 生成From子句
	 * 
     * @param clazz 实体类
	 * @param alias 实体类对应的别名
	 */
	public QueryHelper(Class clazz, String alias) {
		fromClause = "FROM " + clazz.getSimpleName() + " " + alias;
	}

	/**
	 * 拼接Where子句
	 * 
	 * @param condition 查询条件语句;例如:i.title like ?
	 * @param params 查询条件语句中?对应的查询条件值;例如:
	 */
	public QueryHelper addCondition(String condition, Object... params) {
		// 拼接
		if (whereClause.length() > 1) {//非第一个查询条件
			whereClause += " AND " + condition;
		} else {//第一个查询条件
			whereClause = " WHERE " + condition;			
		}

		//设置查询条件值到查询条件值集合中
		if (params != null) {
			for (Object p : params) {
				parameters.add(p);
			}
		}
		return this;
	}

	/**
	 * 如果第一个参数为true,则拼接Where子句
	 * 
	 * @param append
	 * @param condition
	 * @param params
	 */
	public QueryHelper addCondition(boolean append, String condition, Object... params) {
		if (append) {
			addCondition(condition, params);
		}
		return this;
	}

	/**
	 * 拼接OrderBy子句
	 * 
	 * @param propertyName
	 *            参与排序的属性名
	 * @param order 
	 *            排序
	 */
	public QueryHelper addOrderProperty(String property, String order) {
		if (orderByClause.length() > 1) {
			orderByClause += ", " + property +" "+order;
		} else {
			orderByClause = " ORDER BY " + property +" "+order;
		}
		return this;
	}

	/**
	 * 如果第一个参数为true,则拼接OrderBy子句
	 * 
	 * @param append 判断是否可以追加的条件
	 * @param propertyName  属性名
	 * @param order 排序
	 */
	public QueryHelper addOrderProperty(boolean append, String propertyName, String order) {
		if (append) {
			addOrderProperty(propertyName, order);
		}
		return this;
	}

	/**
	 * 获取生成的用于查询数据列表的HQL语句
	 * 
	 * @return
	 */
	public String getQueryListHql() {
		return fromClause + whereClause + orderByClause;
	}

	/**
	 * 获取生成的用于查询总记录数的HQL语句
	 * 
	 * @return
	 */
	public String getQueryCountHql() {
		return "SELECT COUNT(*) " + fromClause + whereClause;
	}

	/**
	 * 获取HQL中的参数值列表
	 * 
	 * @return
	 */
	public List<Object> getParameters() {
		return parameters;
	}

	/**
	 * 查询分页信息,并放到值栈栈顶
	 * 
	 * @param service  //baseDao
	 * @param pageNum  //页数
	 * @param pageSize  //每页数量
	 */
	public void preparePageBean(BaseDao<?> service, int pageNum, int pageSize) {
		PageResult pageResult = service.getPageResult( this,pageNum, pageSize);
		ActionContext.getContext().getValueStack().push(pageResult);
	}

}

以下三个代码是baseDao中的代码

@Override
	public List<T> findObjects(QueryHelper queryHelper) {
		Query query = getSession().createQuery(queryHelper.getQueryListHql());
		List<Object> parameters = queryHelper.getParameters();
		if(parameters != null){
			for(int i = 0; i < parameters.size(); i++){
				query.setParameter(i, parameters.get(i));
			}
		}
		return query.list();
	}
	@Override
	public long count(QueryHelper queryHelper) {
		Query countQuery = getSession().createQuery(queryHelper.getQueryCountHql());
		List<Object> parameters = queryHelper.getParameters();
		if(parameters != null){
			for(int i = 0; i < parameters.size(); i++){
				countQuery.setParameter(i, parameters.get(i));
			}
		}
		System.out.println(countQuery+"baseDaoImpl");
		return (Long) countQuery.uniqueResult(); // 执行查询;
	}
	@Override
	public PageResult getPageResult(QueryHelper queryHelper, int currentPage, int pageSize) {
			System.out.println("-------> DaoSupportImpl.getPageBean( int pageNum, int pageSize, QueryHelper queryHelper )");

			// 参数列表
			List<Object> parameters = queryHelper.getParameters();

			// 查询本页的数据列表
			Query listQuery = getSession().createQuery(queryHelper.getQueryListHql()); // 创建查询对象
			if (parameters != null) { // 设置参数
				for (int i = 0; i < parameters.size(); i++) {
					listQuery.setParameter(i, parameters.get(i));
				}
			}
			listQuery.setFirstResult((currentPage - 1) * pageSize);
			listQuery.setMaxResults(pageSize);
			List list = listQuery.list(); // 执行查询
			// 查询总记录数量
			Query countQuery = getSession().createQuery(queryHelper.getQueryCountHql());
			if (parameters != null) { // 设置参数
				for (int i = 0; i < parameters.size(); i++) {
					countQuery.setParameter(i, parameters.get(i));
				}
			}
			Long count = (Long) countQuery.uniqueResult(); // 执行查询

			return new PageResult(currentPage, pageSize, count, list);
		}

问题解惑

对于queryhelper的代码不做过多的讲解,针对自己做的过程中犯得一些疑惑做讲解

1)i.title like ?中它是参照着数据库SQL语句写的还是针对entity对象写的?

答:经过测试是针对entity对象写的
自己在编写软件的时候,所编写的代码如下:

queryHelper.addCondition("i.bus.busId = ?", busId)			    
						           .addCondition("i.idate = ?", new SimpleDateFormat("yyyy-MM-dd").parse(idate));
						if(inspect!=null && inspect.getInspectId()!=null){//如果不为空就添加查询项
						    queryHelper.addCondition("i.inspectId != ?",inspect.getInspectId());		    
						}	
					    x = inspectService.count(queryHelper);	//获得查询值	
2)QueryHelper中的parameters有什么用,没看到类里用它呀?既然没用为什么还要写入代码里?

答:不是没用,而是很有用,QueryHelper是基于query来做的,在SSH框架里,不用QueryHelper,我们在dao层中也需要写入如下代码,以便从数据库中查询出数据来:

Query query = getSession().createQuery(//
	        		"FROM Department WHERE parent_id = ?")//
	        		.setParameter(0, id);

其中就包含setParameter(0, id);
所以在QueryHelper存在parameters,用来存放一段SQL代码中所有的参数,并通过for循环逐个写出。

3)在某些分页显示的过程中没有看到往前端传递列表,分页就实现了,这是为什么?

答:并不是没有传递列表,只是隐含起来了,你没看到,action中的代码你确实看不到,你可以看看baseAction
action中的代码(注:action这段代码是从别的地方拷贝的,其特点就是写的很多,隐藏了传递列表的情况,比较典型)

new QueryHelper(Topic.class, "t")//
				// 过滤条件
				.addCondition("t.forum=?", forum)//
				.addCondition((viewType == 1), "t.type=?", Topic.TYPE_BEST) // 1 表示只看精华帖
				// 排序条件
				.addOrderProperty((orderBy == 1), "t.lastUpdateTime", asc) // 1 表示只按最后更新时间排序
				.addOrderProperty((orderBy == 2), "t.postTime", asc) // 2 表示只按主题发表时间排序
				.addOrderProperty((orderBy == 3), "t.replyCount", asc) // 3 表示只按回复数量排序
				.addOrderProperty((orderBy == 0), "(CASE t.type WHEN 2 THEN 2 ELSE 0 END)", false)//
				.addOrderProperty((orderBy == 0), "t.lastUpdateTime", false) // 0 表示默认排序(所有置顶帖在前面,并按最后更新时间降序排列)
				.preparePageBean(topicService, pageNum, pageSize);

这个是BaseAction中的代码

public abstract class BaseAction extends ActionSupport {

	protected String[] selectedRow;
	protected PageResult pageResult;
	protected int pageNum = 1;
	protected int pageSize = 10;
	//下面是get和set方法 略

看到了吗?通过BaseAction中的pageResult将七个参数传递过去了。
下面是PageResult 的代码,主要就是返回给前端页面结果用的,都隐藏在这里了。

public PageResult(  int currentPage,int pageSize, long recordCount,List items) {
		this.currentPage = currentPage;
		this.pageSize = pageSize;
		this.recordCount = recordCount;
		this.items = items;

		// 计算总页码
		totalPageCount = (int)((recordCount + pageSize - 1) / pageSize);

		// 计算 beginPageIndex 和 endPageIndex
		// >> 总页数不多于10页,则全部显示
		if (totalPageCount <= 10) {
			beginPageIndex = 1;
			endPageIndex = totalPageCount;
		}
		// >> 总页数多于10页,则显示当前页附近的共10个页码
		else {
			// 当前页附近的共10个页码(前4个 + 当前页 + 后5个)
			beginPageIndex = currentPage - 4;
			endPageIndex = currentPage + 5;
			// 当前面的页码不足4个时,则显示前10个页码
			if (beginPageIndex < 1) {
				beginPageIndex = 1;
				endPageIndex = 10;
			}
			// 当后面的页码不足5个时,则显示后10个页码
			if (endPageIndex > totalPageCount) {
				endPageIndex = totalPageCount;
				beginPageIndex = totalPageCount - 10 + 1;
			}
		}
	}

PageResult.java的目的就是将送入进去的四个参数,计算出剩余的三个参数。这样就可以通过获得PageResult来获取这七个涉及分页的参数了,其中就包括显示页面内容的list,你没看到,只是隐藏起来了而已。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值