OA-分页查询(抽象最终版)二

来源:互联网 发布:上海美工培训班 编辑:程序博客网 时间:2024/06/14 17:58

 上篇文章我们已经把前台和工具类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>


0 0
原创粉丝点击