/** * 定義一個查詢條件容器 * @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);