zoukankan      html  css  js  c++  java
  • OA-分页查询(抽象最终版)二

     上篇文章我们已经把前台和工具类PageBean抽象出来了,下面我们继续抽象:

          比如我们要查询板块的信息时,我们要将板块的信息,以及是否要排序和按照什么排序都要在hql语句中声明,但是我换了一个主题信息查询呢,上面那些东西我们还要继续赋值,传值,再次做了一些重复性的事情。

    还有一个问题,我们在拼接hql语句时,以及order by的时候,总是会出现语句错误,如果字段再多的话,相信大家就已经疯了,那好,我们继续来抽象,看下面代码:

    QueryHelper工具类:

    <span style="font-size:18px;">package cn.itcast.oa.util;
    
    import java.util.ArrayList;
    import java.util.List;
    
    import cn.itcast.oa.base.DaoSupport;
    import cn.itcast.oa.domain.PageBean;
    
    import com.opensymphony.xwork2.ActionContext;
    
    /**
     * 用于辅助拼接HQL语句
     * 
     * @author 志鹏
     * 
     */
    public class QueryHelper {
    
    	private String fromClause; // FROM子句
    	private String whereClause = ""; // Where子句
    	private String orderByClause = ""; // OrderBy子句
    
    	private List<Object> parameters = new ArrayList<Object>(); // 参数列表
    
    	/**
    	 * 生成From子句
    	 * 
    	 * @param clazz
    	 * @param alias
    	 *            别名
    	 */
    	public QueryHelper(Class clazz, String alias) {
    		fromClause = "FROM " + clazz.getSimpleName() + " " + alias;
    	}
    
    	/**
    	 * 拼接Where子句
    	 * 
    	 * @param condition
    	 * @param params
    	 */
    	public QueryHelper addCondition(String condition, Object... params) {
    		// 拼接
    		if (whereClause.length() == 0) {
    			whereClause = " WHERE " + condition;
    		} else {
    			whereClause += " AND " + 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 asc
    	 *            true表示升序,false表示降序
    	 */
    	public QueryHelper addOrderProperty(String propertyName, boolean asc) {
    		if (orderByClause.length() == 0) {
    			orderByClause = " ORDER BY " + propertyName + (asc ? " ASC" : " DESC");
    		} else {
    			orderByClause += ", " + propertyName + (asc ? " ASC" : " DESC");
    		}
    		return this;
    	}
    
    	/**
    	 * 如果第一个参数为true,则拼接OrderBy子句
    	 * 
    	 * @param append
    	 * @param propertyName
    	 * @param asc
    	 */
    	public QueryHelper addOrderProperty(boolean append, String propertyName, boolean asc) {
    		if (append) {
    			addOrderProperty(propertyName, asc);
    		}
    		return this;
    	}
    
    	/**
    	 * 获取生成的用于查询数据列表的HQL语句
    	 * 
    	 * @return
    	 */
    	public String getListQueryHql() {
    		return fromClause + whereClause + orderByClause;
    	}
    
    	/**
    	 * 获取生成的用于查询总记录数的HQL语句
    	 * 
    	 * @return
    	 */
    	public String getCountQueryHql() {
    		return "SELECT COUNT(*) " + fromClause + whereClause;
    	}
    
    	/**
    	 * 获取HQL中的参数值列表
    	 * 
    	 * @return
    	 */
    	public List<Object> getParameters() {
    		return parameters;
    	}
    
    	/**
    	 * 查询分页信息,并放到值栈栈顶
    	 * 
    	 * @param service
    	 * @param pageNum
    	 * @param pageSize
    	 */
    	public void preparePageBean(DaoSupport<?> service, int pageNum, int pageSize) {
    		PageBean pageBean = service.getPageBean(pageNum, pageSize, this);
    		ActionContext.getContext().getValueStack().push(pageBean);
    	}
    
    }
    </span>

    简单介绍,如果我们的参数过多,我们可以根据循环来进行赋值,这样都避免了赋值繁杂,和一些空格的错误了。

    OA系统的抽象不仅仅这些,比如一些公共的GetById(),FindAll()等等这样公共的底层方法,我们都抽象到了一个叫做DaoSupportImpl这样的实现类中,那么我们的分页功能也有这样的公共方法我们依旧抽象出来放在DaoSupportImpl实现类中,看下面代码:

    PageBean方法:

    <span style="font-size:18px;">// 公共的查询分页信息的方法(最终版)
    		public PageBean getPageBean(int pageNum, int pageSize, QueryHelper queryHelper) {
    			
    			// 参数列表
    			List<Object> parameters = queryHelper.getParameters();
    
    			// 查询本页的数据列表
    			Query listQuery = getSession().createQuery(queryHelper.getListQueryHql()); // 创建查询对象
    			if (parameters != null) { // 设置参数
    				for (int i = 0; i < parameters.size(); i++) {
    					listQuery.setParameter(i, parameters.get(i));
    				}
    			}
    			listQuery.setFirstResult((pageNum - 1) * pageSize);
    			listQuery.setMaxResults(pageSize);
    			List list = listQuery.list(); // 执行查询
    
    			// 查询总记录数量
    			Query countQuery = getSession().createQuery(queryHelper.getCountQueryHql());
    			if (parameters != null) { // 设置参数
    				for (int i = 0; i < parameters.size(); i++) {
    					countQuery.setParameter(i, parameters.get(i));
    				}
    			}
    			Long count = (Long) countQuery.uniqueResult(); // 执行查询
    
    			return new PageBean(pageNum, pageSize, count.intValue(), list);
    		}
    	
    	</span>

    大家也许会奇怪,那怎么进行具体的查询呢,比如我是板块查询,没有看到真正的hql语句和表的查询呀,当然我们一些特殊的我们会进行重写呀,比如下面这段代码,就是重写的过程:

    <span style="font-size:18px;">public PageBean getPageBeanByForum(int pageNum, int pageSize, Forum forum) {
    
    		// 查询本页的数据列表
    		List list = getSession().createQuery(//
    				"FROM Topic t WHERE t.forum=? ORDER BY (CASE t.type WHEN 2 THEN 2 ELSE 0 END) DESC, t.lastUpdateTime DESC")//
    				.setParameter(0, forum)//
    				.setFirstResult((pageNum - 1) * pageSize)//
    				.setMaxResults(pageSize)//
    				.list();
    
    		// 查询总记录数量
    		Long count = (Long) getSession().createQuery(//
    				"SELECT COUNT(*) FROM Topic t WHERE t.forum=?")//
    				.setParameter(0, forum)//
    				.uniqueResult();
    
    		return new PageBean(pageNum, pageSize, count.intValue(), list);
    	}</span>

    关于这段内容都这些了,让我很疑惑的是,在action中的hql语句,是不是会让我们的架构设计不够明确呢,hql语句应该放在底层,而不是Action呀,看下面代码:

    Action代码:

    <span style="font-size:18px;">// 准备分页信息 ,最终版
    		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);
    </span>


  • 相关阅读:
    简单验证码实现(Ajax)
    JS获取地址栏参数
    【转】将datatable数据转化成list
    【转】 GridView 72般绝技
    【转】AspNetPager分页控件用法
    【转】 js怎么区分出点击的是鼠标左键还是右键?
    Django~Databases
    Django~static files
    Python—>Mysql—>Dbvisualizer
    含中文数字的名称排序
  • 原文地址:https://www.cnblogs.com/xzpblog/p/5117910.html
Copyright © 2011-2022 走看看