spring data jpa的动态查询封装
/** * 定义一个查询条件容器 * @author lee * * @param <T> */public class Criteria<T> implements Specification<T>{private List<Criterion> criterions = new ArrayList<Criterion>();public Predicate toPredicate(Root<T> root, CriteriaQuery<?> query,CriteriaBuilder builder) {if (!criterions.isEmpty()) {List<Predicate> predicates = new ArrayList<Predicate>();for(Criterion c : criterions){predicates.add(c.toPredicate(root, query,builder));}// 将所有条件用 and 联合起来if (predicates.size() > 0) {return builder.and(predicates.toArray(new Predicate[predicates.size()]));}}return builder.conjunction();}/** * 增加简单条件表达式 * @Methods Name add * @Create In 2012-2-8 By lee * @param expression0 void */public void add(Criterion criterion){if(criterion!=null){criterions.add(criterion);}}}
?然后是各种条件组装类,我首先做了一个接口来包装各种条件
/** * 条件接口 * 用户提供条件表达式接口 * @Class Name Criterion * @Author lee * @Create In 2012-2-8 */public interface Criterion {public enum Operator {EQ, NE, LIKE, GT, LT, GTE, LTE, AND, OR}public Predicate toPredicate(Root<?> root, CriteriaQuery<?> query,CriteriaBuilder builder);}
?然后是针对不同类型条件处理的实现
一个是简单比较类型的处理
?
/** * 简单条件表达式 * @author lee * */public class SimpleExpression implements Criterion{private String fieldName;//属性名private Object value;//对应值private Operator operator;//计算符protected SimpleExpression(String fieldName, Object value, Operator operator) {this.fieldName = fieldName;this.value = value;this.operator = operator;}public String getFieldName() {return fieldName;}public Object getValue() {return value;}public Operator getOperator() {return operator;}@SuppressWarnings({ "rawtypes", "unchecked" })public Predicate toPredicate(Root<?> root, CriteriaQuery<?> query,CriteriaBuilder builder) {Path expression = null;if(fieldName.contains(".")){String[] names = StringUtils.split(fieldName, ".");expression = root.get(names[0]);for (int i = 1; i < names.length; i++) {expression = expression.get(names[i]);}}else{expression = root.get(fieldName);}switch (operator) {case EQ:return builder.equal(expression, value);case NE:return builder.notEqual(expression, value);case LIKE:return builder.like((Expression<String>) expression, "%" + value + "%");case LT:return builder.lessThan(expression, (Comparable) value);case GT:return builder.greaterThan(expression, (Comparable) value);case LTE:return builder.lessThanOrEqualTo(expression, (Comparable) value);case GTE:return builder.greaterThanOrEqualTo(expression, (Comparable) value);default:return null;}}}
?一个逻辑条件计算实现
/** * 逻辑条件表达式 用于复杂条件时使用,如但属性多对应值的OR查询等 * @author lee * */public class LogicalExpression implements Criterion {private Criterion[] criterion; // 逻辑表达式中包含的表达式private Operator operator;//计算符public LogicalExpression(Criterion[] criterions, Operator operator) {this.criterion = criterions;this.operator = operator;}public Predicate toPredicate(Root<?> root, CriteriaQuery<?> query,CriteriaBuilder builder) {List<Predicate> predicates = new ArrayList<Predicate>();for(int i=0;i<this.criterion.length;i++){predicates.add(this.criterion[i].toPredicate(root, query, builder));}switch (operator) {case OR:return builder.or(predicates.toArray(new Predicate[predicates.size()]));default:return null;}}}
?添加一个组装工厂类
/** * 条件构造器 * 用于创建条件表达式 * @Class Name Restrictions * @Author lee */public class Restrictions {/** * 等于 * @param fieldName * @param value * @param ignoreNull * @return */public static SimpleExpression eq(String fieldName, Object value, boolean ignoreNull) {if(StringUtils.isEmpty(value))return null;return new SimpleExpression (fieldName, value, Operator.EQ);}/** * 不等于 * @param fieldName * @param value * @param ignoreNull * @return */public static SimpleExpression ne(String fieldName, Object value, boolean ignoreNull) {if(StringUtils.isEmpty(value))return null;return new SimpleExpression (fieldName, value, Operator.NE);}/** * 模糊匹配 * @param fieldName * @param value * @param ignoreNull * @return */public static SimpleExpression like(String fieldName, String value, boolean ignoreNull) {if(StringUtils.isEmpty(value))return null;return new SimpleExpression (fieldName, value, Operator.LIKE);}/** * * @param fieldName * @param value * @param matchMode * @param ignoreNull * @return */public static SimpleExpression like(String fieldName, String value,MatchMode matchMode, boolean ignoreNull) {if(StringUtils.isEmpty(value))return null;return null;}/** * 大于 * @param fieldName * @param value * @param ignoreNull * @return */public static SimpleExpression gt(String fieldName, Object value, boolean ignoreNull) {if(StringUtils.isEmpty(value))return null;return new SimpleExpression (fieldName, value, Operator.GT);}/** * 小于 * @param fieldName * @param value * @param ignoreNull * @return */public static SimpleExpression lt(String fieldName, Object value, boolean ignoreNull) {if(StringUtils.isEmpty(value))return null;return new SimpleExpression (fieldName, value, Operator.LT);}/** * 大于等于 * @param fieldName * @param value * @param ignoreNull * @return */public static SimpleExpression lte(String fieldName, Object value, boolean ignoreNull) {if(StringUtils.isEmpty(value))return null;return new SimpleExpression (fieldName, value, Operator.GTE);}/** * 小于等于 * @param fieldName * @param value * @param ignoreNull * @return */public static SimpleExpression gte(String fieldName, Object value, boolean ignoreNull) {if(StringUtils.isEmpty(value))return null;return new SimpleExpression (fieldName, value, Operator.LTE);}/** * 并且 * @param criterions * @return */public static LogicalExpression and(Criterion... criterions){return new LogicalExpression(criterions, Operator.AND);}/** * 或者 * @param criterions * @return */public static LogicalExpression or(Criterion... criterions){return new LogicalExpression(criterions, Operator.OR);}/** * 包含于 * @param fieldName * @param value * @return */@SuppressWarnings("rawtypes")public static LogicalExpression in(String fieldName, Collection value, boolean ignoreNull) {if(ignoreNull&&(value==null||value.isEmpty())){return null;}SimpleExpression[] ses = new SimpleExpression[value.size()];int i=0;for(Object obj : value){ses[i]=new SimpleExpression(fieldName,obj,Operator.EQ);i++;}return new LogicalExpression(ses,Operator.OR);}}
?使用方法如下
Criteria<Event> c = new Criteria<Event>();c.add(Restrictions.like("code", searchParam.getCode(), true)); c.add(Restrictions.eq("level", searchParam.getLevel(), false)); c.add(Restrictions.eq("mainStatus", searchParam.getMainStatus(), true)); c.add(Restrictions.eq("flowStatus", searchParam.getFlowStatus(), true)); c.add(Restrictions.eq("createUser.userName", searchParam.getCreateUser(), true)); c.add(Restrictions.lte("submitTime", searchParam.getStartSubmitTime(), true)); c.add(Restrictions.gte("submitTime", searchParam.getEndSubmitTime(), true)); c.add(Restrictions.eq("needFollow", searchParam.getIsfollow(), true)); c.add(Restrictions.ne("flowStatus", CaseConstants.CASE_STATUS_DRAFT, true)); c.add(Restrictions.in("solveTeam.code",teamCodes, true));eventDao.findAll(c);
?其中eventDao为继承JpaSpecificationExecutor的接口类