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

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

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

原来多条件查询的例子:

1@Override 2@Transactional(readOnly = true, rollbackFor = Exception.class ) 3public Page<Dictionary> findByPage(int pageNo, String table, String name,Dictionary pareDict) { 4Page<Dictionary> page = new Page<Dictionary>(); 5page.setAutoCount(true); 6page.setPageNo(pageNo); 7page.setPageSize(5); 89if(name==null || name.equals(“”)){//判断输入条件的空值10if(pareDict!=null){11Query query = getQueryForFind(pareDict.getId(), table);12int count = query.list().size();13List<Dictionary> list = query.setMaxResults(5).setFirstResult((pageNo – 1) * 5).list();14page.setRows(list);15page.setTotal(count);16return page;17}else{18return dictionaryDao.findByCriteria(page,Restrictions.eq(“tableName”, table));19}2021}else{22if(pareDict!=null){//判断输入条件空值23return dictionaryDao.findByCriteria(page,Restrictions.eq(“tableName”, table),24Restrictions.like(“name”, “%”+name+”%”),Restrictions.eq(“parentTable”, pareDict));25}else{26return dictionaryDao.findByCriteria(page,Restrictions.eq(“tableName”, table),27Restrictions.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 * PageQuery<T> {private Page<T> page;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* isCount() {return isCount;}/*** 设置是否计算总数, 默认true* 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* PageQuery<T> setSelectSql(String selectSql) {this.selectSql = selectSql;return this;}private String countSql;/*** 当count语句不能从select简易变化过来的时候使用。 比如有distinct限制的时候* @param countSql* 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的时候例外,该条件会生效* PageQuery<T> addConditon(String filedName, OP op, Object value) {。。。。 }/*** addConditon(String filedName, OP op, Object value) 的简写形式, op 是eq* @param filedName* @param value* PageQuery<T> addConditon(String filedName, Object value) {return this.addConditon(filedName, OP.eq, value);} 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”** 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* 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* 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”** 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* 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* 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* PageQuery<T> addOrderBy(String filedName, OrderType orderType) {。。。。}/*** 执行查询, 在pageQueryService中调用, service可以提供hibernate session对象* @param currentSession* Page<T> excuteQuery(Session currentSession) {。。。。}}

page对象api:

因为有梦,所以勇敢出发,选择出发,便只顾风雨兼程。

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

相关文章:

你感兴趣的文章:

标签云: