package com.jtgh.yjpt.common; import java.util.ArrayList; import java.util.Collection; import java.util.List; import javax.persistence.criteria.CriteriaBuilder; import javax.persistence.criteria.CriteriaBuilder.In; import javax.persistence.criteria.CriteriaQuery; import javax.persistence.criteria.Path; import javax.persistence.criteria.Predicate; import javax.persistence.criteria.Root; import org.apache.commons.lang3.StringUtils; import org.springframework.data.jpa.domain.Specification; import com.jtgh.yjpt.common.PredicateModel.JoinType; /** * Create Specification in the sense of Domain Driven Design * * @author 袁晓冬 * */ public class SpecificationCreater { /** * 根据PredicateModel集合构造查询 * * @param pms * @param clazz * @return */ public static ModelSpecification searchByPredicateModels( Collection pms) { return new ModelSpecification(pms); } /** * 根据PredicateModel集合构造查询 * * @param pms * @param clazz * @return */ public static ModelSpecification searchByPredicateModels_OR( Collection pms) { return new ModelSpecification(pms, PredicateModel.JoinType.OR); } /** * 可以处理PredicateModel模型的Specification * * @author 袁晓冬 * * @param */ public static class ModelSpecification implements Specification { private PredicateModel predicateModel; private List joins = null; public ModelSpecification(Collection pms) { this.predicateModel = new PredicateModel( PredicateModel.JoinType.AND, pms); } /** * 利用or连接查询条件 * * @param pms * @param type */ public ModelSpecification(Collection pms, JoinType type) { this.predicateModel = new PredicateModel(type, pms); } public List getJoins() { return joins; } public void setJoins(List joins) { this.joins = joins; } @Override public Predicate toPredicate(Root root, CriteriaQuery query, CriteriaBuilder cb) { if (null != joins && joins.size() > 0) { for (PredicateJoin join : joins) { root.join( root.getModel().getList(join.getField(), join.getClazz()), join.getType()); } } if (predicateModel == null || (predicateModel.getFieldName() == null && !predicateModel .hasSubPredicateModel())) { // 无查询条件 return cb.conjunction(); } return toPredicateFromModel(predicateModel, root, cb); } @SuppressWarnings({ "unchecked", "rawtypes" }) private Predicate toPredicateFromModel(PredicateModel pm, Root root, CriteriaBuilder cb) { if (pm.hasSubPredicateModel()) {// 处理下级模型 List predicateList = new ArrayList(); for (PredicateModel p : pm.getSubPms()) { predicateList.add(toPredicateFromModel(p, root, cb)); } Predicate[] predicates = new Predicate[predicateList.size()]; predicateList.toArray(predicates); switch (pm.getJoinType()) { case AND: return cb.and(predicates); case OR: return cb.or(predicates); default: return cb.and(predicates); } } else {// 无下级模型时 // nested path translate, 如Task的名为"user.name"的filedName, // 转换为Task.user.name属性 String[] names = StringUtils.split(pm.getFieldName(), "."); Path expression = root.get(names[0]); for (int i = 1; i < names.length; i++) { expression = expression.get(names[i]); } // logic operator switch (pm.getOperator()) { case IN: In in = cb.in(expression); Iterable it = (Iterable) pm.getValue(); for (Object o : it) { in.value(o); } return in; case EQ: return cb.equal(expression, pm.getValue()); case NEQ: return cb.notEqual(expression, pm.getValue()); case LIKE: return cb.like(expression.as(String.class), "%" + pm.getValue() + "%"); case LIKE_L: return cb.like(expression.as(String.class), "%" + pm.getValue()); case LIKE_R: return cb.like(expression.as(String.class), pm.getValue() + "%"); case GT: return cb.greaterThan(expression, (Comparable) pm.getValue()); case LT: return cb.lessThan(expression, (Comparable) pm.getValue()); case GTE: return cb.greaterThanOrEqualTo(expression, (Comparable) pm.getValue()); case LTE: return cb.lessThanOrEqualTo(expression, (Comparable) pm.getValue()); case NL: return cb.isNull(expression); case NNL: return cb.isNotNull(expression); default: return cb.equal(expression, pm.getValue()); } } } } }