zoukankan      html  css  js  c++  java
  • 多条件分页查询,省掉麻烦的空值判断

        在之前做的一个基于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

  • 相关阅读:
    github 代理加速
    centos系统语言设置为中文
    红帽 / CentOS安装Jenkins
    查看api有没有更新到位
    永久关闭Windows10或Windows11的系统自动更新
    api传文件连接超时
    docker日常使用
    开发者工具批量替换
    Linux常用工具安装
    office密钥
  • 原文地址:https://www.cnblogs.com/zdcin/p/3152668.html
Copyright © 2011-2022 走看看