多条件分页查询,省掉麻烦的空值判断

    在之前做的一个基于java的web项目中,有很多多条件查询,每个条件都需要判断下是不是空,然后再拼起来,做组合查询,觉得很烦,就想能不能自己封装一套高层的api,自动忽略空值的条件,自动实现统计总数,自动翻页,等功能;后来又加上了条件优先级,如果某个字段不是空,则其他某个字段不参与查询(就是条件优先级,比如如果条件2不是空,则条件1不生效),这样我就自己写了一个符合这个要求的实现。我觉得这个东西有价值,跟大家分享一下。

    访问数据库我用的hibernate,我的这套api跟hibernate的critical查询比较像,不过我是基于hql拼条件的思路做的,下面看例子:

原来多条件查询的例子:

 1     @Override
 2     @Transactional(readOnly = true, rollbackFor = Exception.class )
 3     public Page<Dictionary> findByPage(int pageNo, String table, String name,Dictionary pareDict) {
 4         Page<Dictionary> page = new Page<Dictionary>();
 5         page.setAutoCount(true);
 6         page.setPageNo(pageNo);
 7         page.setPageSize(5);
 8         
 9         if(name==null || name.equals("")){//判断输入条件的空值
10             if(pareDict!=null){
11                 Query query = getQueryForFind(pareDict.getId(), table);
12                 int count = query.list().size();
13                 List<Dictionary> list = query.setMaxResults(5).setFirstResult((pageNo - 1) * 5).list();
14                 page.setRows(list);
15                 page.setTotal(count);
16                 return page;
17             }else{
18                 return dictionaryDao.findByCriteria(page,Restrictions.eq("tableName", table));
19             }
20             
21         }else{
22             if(pareDict!=null){//判断输入条件空值
23return dictionaryDao.findByCriteria(page,Restrictions.eq("tableName", table),
24 Restrictions.like("name", "%"+name+"%"),Restrictions.eq("parentTable", pareDict));
25             }else{
26                 return dictionaryDao.findByCriteria(page,Restrictions.eq("tableName", table),
27                         Restrictions.like("name", "%"+name+"%"));
28             }
29         }
30 
31     }

这个例子逻辑看不懂没有关系,只要能看出来原来是怎么根据多个条件进行判断的就好了,相信很多做过java的人都会有这方面的经验。

    以下是使用我写的api查询的例子:

    private List<Well> find(Integer jobid, String state, List<String> wellNames) throws Exception {
        
        Page<WellJob> page = new Page<WellJob>();//初始化一个分页查询结果对象,用于接收查询结果
        page.setPageSize(rows.size());//设置一页大小
        PageQuery<WellJob> query = new PageQuery<WellJob>(page);//用page对象构造查询对象
        query.setCount(false);//设定是否自动获取总数,如果获取的话,只会统计一次
        query.addTable(WellJob.class, null);//addtable可以多次调用,用于联合查询,第二个参数是表别名,null的话表示用默认值
        query.addConditon("jobType.id", OP.eq, jobid).and("state", OP.eq, state).and("well.wellNum", OP.in, wellNames);
//addCondition 这个方法表示设置条件的开始,只能调用一次,如果第三个参数是null,则忽略这次方法调用
//add 与条件,如果第三个参数是null,忽略这次方法调用
//query 对象上基本每个api的返回值都是自身,api可以连续调用,编码更流畅
this.pageQueryService.getNextPage(query);//获取下一页,如果page参数从页面上传回来,这个方法就是翻页了 //this.pageQueryService 对象是全局对象,基本上就是个壳,不用关心,主要功能都是在query对象里边实现的

//以下代码都是分析结果的,于查询api关系不大 Set<Long> wellNumSet = new HashSet<Long>(); for (WellJob wj : page.getRows()) { wellNumSet.add(wj.getWell().getId()); } List<Well> result = new ArrayList<Well>(rows.size() - wellNumSet.size()); for (Well w : rows) { if (!wellNumSet.contains(w.getId())) { result.add(w); } } return result; }

    查询对象的主要api:

package com.secneo.common;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import org.apache.commons.lang.xwork.StringUtils;
import org.hibernate.Query;
import org.hibernate.classic.Session;
import org.secneo.framework.orm.hibernate.Page;

/**
 * 分页查询 工具, 原理类似hibernate 的critical工具,但用法上不同, 可以与pageQueryService 配合,在 action中直接使用,
 * 本质上该工具是对hql的封装, 封装后
 * 目的是提供简易的分页查询接口,可以设定为自动计算总条目数。
 * 可以设定条件的替换规则,如 第二个条件不为空时 ,第一个条件则不生效,
 * 
 * @author ZDCIN
 *
 */
public class PageQuery<T> {
    
    private Page<T> page;
//    private List<String> tables = new ArrayList<String>();
    private String where = "";
    private Map<Integer, CondTuple> conditionMap = new HashMap<Integer, CondTuple>();
    private String orderBy = "";
    
    private int conditionIndex = 0;
    private boolean isCount = true;
    
    /**
     * 查看是否计算总数, 默认true, 计算总数的条件是 isCount = true
     * @return
     */
    public boolean isCount() {
        return isCount;
    }
    /**
     * 设置是否计算总数, 默认true
     * @return
     */
    public void setCount(boolean isCount) {
        this.isCount = isCount;
    }
    /**
     * 设定page对象,和返回类型T
     * @param page
     */
    public PageQuery(Page<T> page) {
        this.page = page;
    }

    private String selectSql = "";

    /**
     * 当获取字段不是一个标准bean或者不是一个bean的全部字段的时候使用, 默认不用调用该方法
     * @param selectSql
     * @return
     */
    public PageQuery<T> setSelectSql(String selectSql) {
        this.selectSql = selectSql;
        return this;
    }
    private String countSql;
    
    /**
     * 当count语句不能从select简易变化过来的时候使用。 比如有distinct限制的时候
     * @param countSql
     * @return
     */
    public PageQuery<T> setCountSql(String countSql) {
        this.countSql = countSql;
        return this;
    }

    private String fromSql;
    
    /**
     * 添加要查询的表,并设定别名, 该方法可以多次调用,作为多表联合查询。
     * @param tableClass
     * @param alias  可以为空,表示没有别名
     * @return
     */
    @SuppressWarnings("rawtypes")
    public PageQuery<T> addTable(Class tableClass, String alias) {
       。。。。。
    }

    /**
     * 添加条件, 该方法只能调用一次,且必须在and 或者or之前调用
     * @param filedName 字段名, 别名和字段的组合形式,
     * @param op 字段上的条件操作, 如等于, 大于, in like等,
     * @param value  如果value为空,则该条件不生效,  但当op是 innotnull或者isnull的时候例外,该条件会生效
     * @return
     */
    public PageQuery<T> addConditon(String filedName, OP op, Object value) {
       。。。。
    }


    /**
     *  addConditon(String filedName, OP op, Object value) 的简写形式, op 是eq
     * @param filedName
     * @param value
     * @return
     */
    public PageQuery<T> addConditon(String filedName, Object value) {
        return this.addConditon(filedName, OP.eq, value);
    }

    private static enum LogicOp {
        and, or;
    }

    private PageQuery<T> and_AND_or(LogicOp logicOP, String filedName, OP op, Object value,
            String replaceWhich) {
        。。。。
    }

    /**
     * 添加and条件, where中的条件都是平级的,如果有括号,则用逻辑运算规则拉平
     * 
     * @param filedName  与addConditon中意义相同
     * @param op  与addConditon中意义相同
     * @param value  与addConditon中意义相同
     * @param replaceWhich  替换列表, 如果该方法中value不为空,则替换列表中的字段,如“1,2” 
     * 
     * @return
     */
    public PageQuery<T> and(String filedName, OP op, Object value, String replaceWhich) {
        return this.and_AND_or(LogicOp.and,  filedName, op, value, replaceWhich);
    }

    /**
     * and(String filedName, OP op, Object value, String replaceWhich) 的简写形式
     * @param filedName
     * @param op
     * @param value
     * @return
     */
    public PageQuery<T> and(String filedName, OP op, Object value) {
        return this.and_AND_or(LogicOp.and,  filedName, op, value, null);
    }

    /**
     * and(String filedName, OP op, Object value, String replaceWhich) 的简写形式
     * @param filedName
     * @param value
     * @return
     */
    public PageQuery<T> and(String filedName, Object value) {
        return this.and_AND_or(LogicOp.and,  filedName, OP.eq, value, null);
    }

    /**
     * 添加or条件, where中的条件都是平级的,如果有括号,则用逻辑运算规则拉平
     * 
     * @param filedName  与addConditon中意义相同
     * @param op  与addConditon中意义相同
     * @param value  与addConditon中意义相同
     * @param replaceWhich  替换列表, 如果该方法中value不为空,则替换列表中的字段,如“1,2” 
     * 
     * @return
     */
    public PageQuery<T> or(String filedName, OP op, Object value, String replaceWhich) {
        return this.and_AND_or(LogicOp.or,  filedName, op, value, replaceWhich);
    }


    /**
     * 同  or(String filedName, OP op, Object value, String replaceWhich)
     * @param filedName
     * @param op
     * @param value
     * @return
     */
    public PageQuery<T> or(String filedName, OP op, Object value) {
        return this.and_AND_or(LogicOp.or, filedName, op, value, null);
    }

    /**
     * 同  or(String filedName, OP op, Object value, String replaceWhich)
     * @param filedName
     * @param value
     * @return
     */
    public PageQuery<T> or(String filedName, Object value) {
        return this.and_AND_or(LogicOp.or, filedName, OP.eq, value, null);
    }
    
    /**
     * 添加排序, 可调用多次
     * @param filedName  与addConditon中意义相同
     * @param orderType OrderType.ASC, OrderType.DESC
     * @return
     */
    public PageQuery<T> addOrderBy(String filedName, OrderType orderType) {
        。。。。
    }
    
    
    /**
     * 执行查询, 在pageQueryService中调用, service可以提供hibernate session对象
     * @param currentSession
     * @return
     */
    public Page<T> excuteQuery(Session currentSession) {
        。。。。
    }
}

   page对象api:

public class Page<T> {public Page() {
    }
    public Page(Integer pageSize, boolean autoCount) {
    }
    /**
     * 每页的记录数量,默认值 15.
     */
    public Integer getPageSize() {
    }
    public boolean isPageSizeSetted() {
    }
    public void setPageSize(Integer pageSize) {
    }
    /**
     * 当前页的页号,序号从1开始.
     */
    public Integer getPageNo() {
    }
    public void setPageNo(Integer pageNo) {
    }
    /**
     * 第一条记录在结果集中的位置,序号从0开始.
     */
    public Integer getFirst() {
    }
    public boolean isFirstSetted() {
    }
    public boolean isOrderBySetted() {
    }
    /**
     * 是否自动获取总页数,默认为false,query by HQL时本属性无效.
     */
    public boolean isAutoCount() {
    }
    public void setAutoCount(boolean autoCount) {
    }
    /**
     * 页内的数据列表.
     */
    public List<T> getRows() {
    }
    public void setRows(List<T> result) {
    }
    /**
     * 总记录数.
     */
    public Integer getTotal() {
    }
    public void setTotal(Integer totalCount) {
    }
    /**
     * 计算总页数.
     */
    public Integer getTotalPages() {
    }
    /**
     * 是否还有下一页.
     */
    public boolean isHasNext() {
    }

    /**
     * 返回下页的页号,序号从1开始.
     */
    public Integer getNextPage() {
    }
    /**
     * 是否还有上一页.
     */
    public boolean isHasPre() {
    }
    /**
     * 返回上页的页号,序号从1开始.
     */
    public Integer getPrePage() {
    }
    /**
     * 得到分页条件仅支持like查询
     */
    public Map<String, Object> getCondition() {
    }
    public void setCondition(Map<String, Object> condition) {
    }
    /**
     * 多排序条件
     * 
     * @return
     */
    public String[][] getOrderByArr() {
    }
    public void setOrderByArr(String[][] orderByArr) {
    }
    public String getMemo() {
    }
    public void setMemo(String memo) {
    }
}

page对象功能比较直观,但因为大部分代码都不是我写的,page的源码我就不提供了。

    这个api就是为了解决多个条件任意组合的联合查询的问题,省去if判断空值,省去写额外的统计总数代码,还提供条件优先级的功能。

    我的这个代码不会那么容易跑起来,我觉得比代码更重要的是,提供一种简化问题、解决问题的思路。如果读者您对这个问题跟我一样感兴趣,欢迎讨论。

  以下是query对象和queryService对象的的全部源码:

  1 import java.math.BigDecimal;
  2 import java.math.BigInteger;
  3 import java.util.ArrayList;
  4 import java.util.Date;
  5 import java.util.HashMap;
  6 import java.util.List;
  7 import java.util.Locale;
  8 import java.util.Map;
  9 
 10 import org.apache.commons.lang.xwork.StringUtils;
 11 import org.hibernate.Query;
 12 import org.hibernate.classic.Session;
 13 import org.secneo.framework.orm.hibernate.Page;
 14 
 15 /**
 16  * 分页查询 工具, 原理类似hibernate 的critical工具,但用法上不同, 可以与pageQueryService 配合,在 action中直接使用,
 17  * 本质上该工具是对hql的封装, 封装后
 18  * 目的是提供简易的分页查询接口,可以设定为自动计算总条目数。
 19  * 可以设定条件的替换规则,如 第二个条件不为空时 ,第一个条件则不生效,
 20  * 
 21  * @author ZDCIN
 22  *
 23  */
 24 public class PageQuery<T> {
 25     
 26     private Page<T> page;
 27 //    private List<String> tables = new ArrayList<String>();
 28     private String where = "";
 29     private Map<Integer, CondTuple> conditionMap = new HashMap<Integer, CondTuple>();
 30     private String orderBy = "";
 31     
 32     private int conditionIndex = 0;
 33     private boolean isCount = true;
 34     
 35     /**
 36      * 查看是否计算总数, 默认true, 计算总数的条件是 isCount = true
 37      * @return
 38      */
 39     public boolean isCount() {
 40         return isCount;
 41     }
 42     /**
 43      * 设置是否计算总数, 默认true
 44      * @return
 45      */
 46     public void setCount(boolean isCount) {
 47         this.isCount = isCount;
 48     }
 49     /**
 50      * 设定page对象,和返回类型T
 51      * @param page
 52      */
 53     public PageQuery(Page<T> page) {
 54         this.page = page;
 55     }
 56 
 57     private String selectSql = "";
 58 
 59     /**
 60      * 当获取字段不是一个标准bean或者不是一个bean的全部字段的时候使用, 默认不用调用该方法
 61      * @param selectSql
 62      * @return
 63      */
 64     public PageQuery<T> setSelectSql(String selectSql) {
 65         this.selectSql = selectSql;
 66         return this;
 67     }
 68     private String countSql;
 69     
 70     /**
 71      * 当count语句不能从select简易变化过来的时候使用。 比如有distinct限制的时候
 72      * @param countSql
 73      * @return
 74      */
 75     public PageQuery<T> setCountSql(String countSql) {
 76         this.countSql = countSql;
 77         return this;
 78     }
 79 
 80     private String fromSql;
 81     
 82     /**
 83      * 添加要查询的表,并设定别名, 该方法可以多次调用,作为多表联合查询。
 84      * @param tableClass
 85      * @param alias  可以为空,表示没有别名
 86      * @return
 87      */
 88     @SuppressWarnings("rawtypes")
 89     public PageQuery<T> addTable(Class tableClass, String alias) {
 90         if (StringUtils.isBlank(this.fromSql)) {
 91             this.fromSql = " FROM ";
 92         } else {
 93             this.fromSql += ", ";
 94         }
 95         if (StringUtils.isNotBlank(alias)) {
 96             this.fromSql += tableClass.getSimpleName() + " AS " + alias;
 97         } else {
 98             this.fromSql += tableClass.getSimpleName() + " ";
 99         }
100         return this;
101     }
102 
103     /**
104      * 添加条件, 该方法只能调用一次,且必须在and 或者or之前调用
105      * @param filedName 字段名, 别名和字段的组合形式,
106      * @param op 字段上的条件操作, 如等于, 大于, in like等,
107      * @param value  如果value为空,则该条件不生效,  但当op是 innotnull或者isnull的时候例外,该条件会生效
108      * @return
109      */
110     public PageQuery<T> addConditon(String filedName, OP op, Object value) {
111         CondTuple tuple = new CondTuple(null, filedName, op, value, null);
112         this.conditionMap.put(this.conditionIndex ++, tuple);
113         return this;
114 //        if (value == null) {
115 //            return this;
116 //        }
117 //        //String filedFullName = this.filedName(tableIndex, filedName);
118 //        this.condition = " WHERE " + filedName + op.v() + ":" + filedName;
119 //        this.conditionMap.put(filedName, value);
120 //        return this;
121     }
122 
123 
124     /**
125      *  addConditon(String filedName, OP op, Object value) 的简写形式, op 是eq
126      * @param filedName
127      * @param value
128      * @return
129      */
130     public PageQuery<T> addConditon(String filedName, Object value) {
131         return this.addConditon(filedName, OP.eq, value);
132     }
133 
134     private static enum LogicOp {
135         and, or;
136     }
137 
138     private PageQuery<T> and_AND_or(LogicOp logicOP, String filedName, OP op, Object value,
139             String replaceWhich) {
140         CondTuple tuple = new CondTuple(logicOP, filedName, op, value, replaceWhich);
141         this.conditionMap.put(this.conditionIndex ++, tuple);
142         return this;
143 //        if (value == null) {
144 //            return this;
145 //        }
146 //        if (StringUtils.isBlank(this.condition)) {
147 //            this.condition = " WHERE ";
148 //        } else {
149 //            this.condition += " " + logicOP.name() + " ";
150 //        }
151 //        //String filedFullName = this.filedName(tableIndex, filedName);
152 //        this.condition += filedName + op.v() + ":" + filedName;
153 //        this.conditionMap.put(filedName, value);
154 //        return this;
155     }
156 
157     /**
158      * 添加and条件, where中的条件都是平级的,如果有括号,则用逻辑运算规则拉平
159      * 
160      * @param filedName  与addConditon中意义相同
161      * @param op  与addConditon中意义相同
162      * @param value  与addConditon中意义相同
163      * @param replaceWhich  替换列表, 如果该方法中value不为空,则替换列表中的字段,如“1,2” 
164      * 
165      * @return
166      */
167     public PageQuery<T> and(String filedName, OP op, Object value, String replaceWhich) {
168         return this.and_AND_or(LogicOp.and,  filedName, op, value, replaceWhich);
169     }
170 
171     /**
172      * and(String filedName, OP op, Object value, String replaceWhich) 的简写形式
173      * @param filedName
174      * @param op
175      * @param value
176      * @return
177      */
178     public PageQuery<T> and(String filedName, OP op, Object value) {
179         return this.and_AND_or(LogicOp.and,  filedName, op, value, null);
180     }
181 
182     /**
183      * and(String filedName, OP op, Object value, String replaceWhich) 的简写形式
184      * @param filedName
185      * @param value
186      * @return
187      */
188     public PageQuery<T> and(String filedName, Object value) {
189         return this.and_AND_or(LogicOp.and,  filedName, OP.eq, value, null);
190     }
191 
192     /**
193      * 添加or条件, where中的条件都是平级的,如果有括号,则用逻辑运算规则拉平
194      * 
195      * @param filedName  与addConditon中意义相同
196      * @param op  与addConditon中意义相同
197      * @param value  与addConditon中意义相同
198      * @param replaceWhich  替换列表, 如果该方法中value不为空,则替换列表中的字段,如“1,2” 
199      * 
200      * @return
201      */
202     public PageQuery<T> or(String filedName, OP op, Object value, String replaceWhich) {
203         return this.and_AND_or(LogicOp.or,  filedName, op, value, replaceWhich);
204     }
205 
206 
207     /**
208      * 同  or(String filedName, OP op, Object value, String replaceWhich)
209      * @param filedName
210      * @param op
211      * @param value
212      * @return
213      */
214     public PageQuery<T> or(String filedName, OP op, Object value) {
215         return this.and_AND_or(LogicOp.or, filedName, op, value, null);
216     }
217 
218     /**
219      * 同  or(String filedName, OP op, Object value, String replaceWhich)
220      * @param filedName
221      * @param value
222      * @return
223      */
224     public PageQuery<T> or(String filedName, Object value) {
225         return this.and_AND_or(LogicOp.or, filedName, OP.eq, value, null);
226     }
227     
228     /**
229      * 添加排序, 可调用多次
230      * @param filedName  与addConditon中意义相同
231      * @param orderType OrderType.ASC, OrderType.DESC
232      * @return
233      */
234     public PageQuery<T> addOrderBy(String filedName, OrderType orderType) {
235         if (StringUtils.isBlank(filedName)) {
236             return this;
237         }
238         if (StringUtils.isBlank(this.orderBy)) {
239             this.orderBy = " ORDER BY ";
240         } else {
241             this.orderBy += ",";
242         }
243         this.orderBy += filedName + " " + orderType.name();
244         return this;
245     }
246     
247     
248     /**
249      * 执行查询, 在pageQueryService中调用, service可以提供hibernate session对象
250      * @param currentSession
251      * @return
252      */
253     public Page<T> excuteQuery(Session currentSession) {
254         List<Integer> replaceList = this.getReplaceList();
255         this.buildWhereStatementInSql(replaceList);
256        
257         if (page.getTotal() == -1) {
258             String countHql = "SELECT " + (StringUtils.isBlank(this.countSql) ? " COUNT(*) " : this.countSql)
259                     + this.fromSql + this.where;
260 
261             Query hquery = currentSession.createQuery(countHql);
262             this.buildHibernateQuery(replaceList, hquery);
263             Long totalCol = (Long) hquery.uniqueResult();
264 
265             page.setTotal(totalCol.intValue());
266             // page.setPageNo(1);//肯定是从第一页开始
267         }
268         String hql = this.selectSql + this.fromSql + this.where + this.orderBy;
269         System.out.println("query sql is:" + hql);
270         Query hquery = currentSession.createQuery(hql);
271         this.buildHibernateQuery(replaceList, hquery);
272         @SuppressWarnings("unchecked")
273         List<T> resultSet= hquery.setFirstResult(this.page.getFirst()).setMaxResults(this.page.getPageSize()).list();
274         this.page.setRows(resultSet);
275         return this.page;
276     }
277     
278     private void buildHibernateQuery(List<Integer> replaceList, Query hquery) {
279         for (int i = 0; i < this.conditionIndex; i++) {
280             CondTuple tuple = this.conditionMap.get(i);
281             if (replaceList.contains(i)) {
282                 continue;
283             }
284             if (tuple.value != null && !tuple.op.equals(OP.in)) {
285                 this.putObjectToHql(hquery, tuple.valueNameInHql + i, tuple.value);
286             }
287         }
288     }
289 
290     private void putObjectToHql(Query hquery, String valueNameInHql, Object value) {
291 //        valueNameInHql = valueNameInHql.replace('.', '_');
292       //valueName 是hql中的冒号后边的单词,用于hql执行时用变量替换,里边不能含有下列字符
293 //        String valueNameInHql =  valueNameInHql;
294         valueNameInHql = valueNameInHql.replace('.', '_');
295         valueNameInHql = valueNameInHql.replaceAll(" ", "");
296         valueNameInHql = valueNameInHql.replaceAll("-", "");
297         valueNameInHql = valueNameInHql.replaceAll("\(", "");
298         valueNameInHql = valueNameInHql.replaceAll("\)", "");
299         if (value instanceof Long) {
300             hquery.setLong(valueNameInHql, (Long) value);
301         } else if (value instanceof String) {
302             hquery.setString(valueNameInHql, (String) value);
303         } else if (value instanceof Date) {
304             hquery.setTimestamp(valueNameInHql, (Date) value);
305         } else if (value instanceof BigDecimal) {
306             hquery.setBigDecimal(valueNameInHql, (BigDecimal) value);
307         } else if (value instanceof Integer) {
308             hquery.setInteger(valueNameInHql, (Integer) value);
309         } else if (value instanceof Double) {
310             hquery.setDouble(valueNameInHql, (Double) value);
311         } else if (value instanceof Float) {
312             hquery.setFloat(valueNameInHql, (Float) value);
313         } else if (value instanceof Boolean) {
314             hquery.setBoolean(valueNameInHql, (Boolean) value);
315         } else if (value instanceof byte[]) {
316             hquery.setBinary(valueNameInHql, (byte[]) value);
317         } else if (value instanceof Locale) {
318             hquery.setLocale(valueNameInHql, (Locale) value);
319         } else if (value instanceof BigInteger) {
320             hquery.setBigInteger(valueNameInHql, (BigInteger) value);
321         } else {
322             throw new RuntimeException("不支持的value类型:" + value.getClass());
323         }
324         // 下面这些不常用,且麻烦,不支持
325         // setText(String, String)
326         // setSerializable(String, Serializable)
327         // setDate(String, Date)
328         // setTime(String, Date)
329         // setCalendar(String, Calendar)
330         // setCalendarDate(String, Calendar)
331         // setCharacter(String, char)
332         // setByte(String, byte)
333         // setShort(String, short)
334     }
335 
336     private void buildWhereStatementInSql(List<Integer> replaceList) {
337         for (int i = 0; i < this.conditionIndex; i++) {
338             CondTuple tuple = this.conditionMap.get(i);
339             if (replaceList.contains(i)) {
340                 continue;
341             }
342             if (tuple.value != null) {
343                 //in 查询特殊处理
344                 if (tuple.op.equals(OP.in)) {
345                     List value = (List)tuple.value;
346                     String temp = "";
347                     if (value == null || value.size() == 0) {
348                         break;
349                     }
350                     if (value.get(0) instanceof String) {
351                         temp = "('";
352                         for (String subv : (List<String>)value) {
353                             temp += subv + "','";
354                         }
355                         temp += "')";
356                         temp = temp.replace(",')", "')");
357                     } else if (value.get(0) instanceof Long){
358                         temp = "(";
359                         for (Long subv : (List<Long>)value) {
360                             temp += subv.longValue() + ",";
361                         }
362                         temp += ")";
363                         temp = temp.replace(",)", ")");
364                     }else {
365                         temp = "(";
366                         for (Integer subv : (List<Integer>)value) {
367                             temp += subv.intValue() + ",";
368                         }
369                         temp += ")";
370                         temp = temp.replace(",)", ")");
371                     }
372                     this.where += (tuple.logicOp == null ? "" : tuple.logicOp.name()) + " " +  tuple.valueNameInHql + tuple.op.v()
373                             + temp + " ";
374                 } else {
375                     //valueName 是hql中的冒号后边的单词,用于hql执行时用变量替换,里边不能含有下列字符
376                     String valueName =  tuple.valueNameInHql + i;
377                     valueName = valueName.replace('.', '_');
378                     valueName = valueName.replaceAll(" ", "");
379                     valueName = valueName.replaceAll("-", "");
380                     valueName = valueName.replaceAll("\(", "");
381                     valueName = valueName.replaceAll("\)", "");
382                     this.where += (tuple.logicOp == null ? "" : tuple.logicOp.name()) + " " + tuple.valueNameInHql
383                             + tuple.op.v() + ":" + valueName + " ";
384                 }
385             } else {
386                 if (tuple.op.equals(OP.isNull) || tuple.op.equals(OP.isNotNull)) {
387                     this.where += (tuple.logicOp == null ? "" : tuple.logicOp.name()) + " " + tuple.valueNameInHql
388                             + tuple.op.v()  + " ";
389                 }
390             }
391         }
392         if (StringUtils.isNotBlank(this.where)) {
393             this.where = " WHERE " + this.where;
394             if (this.where.contains("WHERE and")) {
395                 this.where.replace("WHERE and", "WHERE ");
396             } else if (this.where.contains("WHERE or")) {
397                 this.where.replace("WHERE or", "WHERE ");
398             }
399         }
400     }
401     private List<Integer> getReplaceList() {
402         List<Integer> result = new ArrayList<Integer>();
403         String replaceString = "";
404         for (int i = 0; i < this.conditionIndex; i++) {
405             CondTuple tuple = this.conditionMap.get(i);
406             if (tuple.value != null && StringUtils.isNotBlank(tuple.replaceString)) {
407                 replaceString += tuple.replaceString;
408             }
409         }
410         String[] temp = replaceString.split(",");
411         if (temp == null || temp.length == 0) {
412             return result;
413         }
414         for (String t : temp) {
415             if (StringUtils.isBlank(t)) {
416                 continue;
417             }
418             if (!result.contains(t)) {
419                 result.add(Integer.parseInt(t));
420             }
421         }
422         return result;
423     }
424     
425     
426 
427     /**条件组合对象*/
428     private static class CondTuple {
429         CondTuple(LogicOp logicOp, String valueNameInHql, OP op, Object value, String replaceString) {
430             this.logicOp = logicOp;
431             this.valueNameInHql = valueNameInHql;
432             this.op = op;
433             this.value = value;
434             this.replaceString = replaceString;
435         }
436 
437         LogicOp logicOp;
438         String valueNameInHql;
439         OP op;
440         Object value;
441         String replaceString;
442     }
443     public static enum OrderType {
444         ASC,DESC;
445     }
446     public static enum OP {
447         eq {
448             {
449                 value = "=";
450             }
451         },
452         neq {
453             {
454                 value = "<>";
455             }
456         },
457         gt {
458             {
459                 value = ">";
460             }
461         },
462         lt {
463             {
464                 value = "<";
465             }
466         },
467         ge {
468             {
469                 value = ">=";
470             }
471         },
472         le {
473             {
474                 value = "<=";
475             }
476         },
477         like {
478             {
479                 value = " like ";
480             }
481         },
482         in {
483             {
484                 value = " in ";
485             }
486         }, 
487         isNotNull {
488             {
489                 value = " is not null ";
490             }
491         },
492         isNull {
493             {
494                 value = " is null ";
495             }
496         };
497         protected String value = null;
498 
499         public String v() {
500             return value;
501         }
502     }
503 
504     
505 }
View Code
 1 @Service("pageQueryService")
 2 public class PageQueryService {
 3     
 4     private SessionFactory sessionFactory;
 5 
 6     @Resource(name = "sessionFactory")
 7     public void setSessionFactory(SessionFactory sessionFactory) {
 8         this.sessionFactory = sessionFactory;
 9     }
10 
11     public <T> Page<T> getNextPage(PageQuery<T> pageQuery) {
12         Page<T> result = pageQuery.excuteQuery(this.sessionFactory.getCurrentSession());
13         return result;
14     }
15 }
View Code

原文地址:http://www.cnblogs.com/zdcin/p/3152668.html

原文地址:https://www.cnblogs.com/zdcin/p/3152668.html