123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170 |
- 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 <T> ModelSpecification<T> searchByPredicateModels(
- Collection<PredicateModel> pms) {
- return new ModelSpecification<T>(pms);
- }
- /**
- * 根据PredicateModel集合构造查询
- *
- * @param pms
- * @param clazz
- * @return
- */
- public static <T> ModelSpecification<T> searchByPredicateModels_OR(
- Collection<PredicateModel> pms) {
- return new ModelSpecification<T>(pms, PredicateModel.JoinType.OR);
- }
- /**
- * 可以处理PredicateModel模型的Specification
- *
- * @author 袁晓冬
- *
- * @param <T>
- */
- public static class ModelSpecification<T> implements Specification<T> {
- private PredicateModel predicateModel;
- private List<PredicateJoin> joins = null;
- public ModelSpecification(Collection<PredicateModel> pms) {
- this.predicateModel = new PredicateModel(
- PredicateModel.JoinType.AND, pms);
- }
- /**
- * 利用or连接查询条件
- *
- * @param pms
- * @param type
- */
- public ModelSpecification(Collection<PredicateModel> pms, JoinType type) {
- this.predicateModel = new PredicateModel(type, pms);
- }
- public List<PredicateJoin> getJoins() {
- return joins;
- }
- public void setJoins(List<PredicateJoin> joins) {
- this.joins = joins;
- }
- @Override
- public Predicate toPredicate(Root<T> 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<T> root,
- CriteriaBuilder cb) {
- if (pm.hasSubPredicateModel()) {// 处理下级模型
- List<Predicate> predicateList = new ArrayList<Predicate>();
- 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());
- }
- }
- }
- }
- }
|