SpecificationCreater.java 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. package com.jtgh.yjpt.common;
  2. import java.util.ArrayList;
  3. import java.util.Collection;
  4. import java.util.List;
  5. import javax.persistence.criteria.CriteriaBuilder;
  6. import javax.persistence.criteria.CriteriaBuilder.In;
  7. import javax.persistence.criteria.CriteriaQuery;
  8. import javax.persistence.criteria.Path;
  9. import javax.persistence.criteria.Predicate;
  10. import javax.persistence.criteria.Root;
  11. import org.apache.commons.lang3.StringUtils;
  12. import org.springframework.data.jpa.domain.Specification;
  13. import com.jtgh.yjpt.common.PredicateModel.JoinType;
  14. /**
  15. * Create Specification in the sense of Domain Driven Design
  16. *
  17. * @author 袁晓冬
  18. *
  19. */
  20. public class SpecificationCreater {
  21. /**
  22. * 根据PredicateModel集合构造查询
  23. *
  24. * @param pms
  25. * @param clazz
  26. * @return
  27. */
  28. public static <T> ModelSpecification<T> searchByPredicateModels(
  29. Collection<PredicateModel> pms) {
  30. return new ModelSpecification<T>(pms);
  31. }
  32. /**
  33. * 根据PredicateModel集合构造查询
  34. *
  35. * @param pms
  36. * @param clazz
  37. * @return
  38. */
  39. public static <T> ModelSpecification<T> searchByPredicateModels_OR(
  40. Collection<PredicateModel> pms) {
  41. return new ModelSpecification<T>(pms, PredicateModel.JoinType.OR);
  42. }
  43. /**
  44. * 可以处理PredicateModel模型的Specification
  45. *
  46. * @author 袁晓冬
  47. *
  48. * @param <T>
  49. */
  50. public static class ModelSpecification<T> implements Specification<T> {
  51. private PredicateModel predicateModel;
  52. private List<PredicateJoin> joins = null;
  53. public ModelSpecification(Collection<PredicateModel> pms) {
  54. this.predicateModel = new PredicateModel(
  55. PredicateModel.JoinType.AND, pms);
  56. }
  57. /**
  58. * 利用or连接查询条件
  59. *
  60. * @param pms
  61. * @param type
  62. */
  63. public ModelSpecification(Collection<PredicateModel> pms, JoinType type) {
  64. this.predicateModel = new PredicateModel(type, pms);
  65. }
  66. public List<PredicateJoin> getJoins() {
  67. return joins;
  68. }
  69. public void setJoins(List<PredicateJoin> joins) {
  70. this.joins = joins;
  71. }
  72. @Override
  73. public Predicate toPredicate(Root<T> root, CriteriaQuery<?> query,
  74. CriteriaBuilder cb) {
  75. if (null != joins && joins.size() > 0) {
  76. for (PredicateJoin join : joins) {
  77. root.join(
  78. root.getModel().getList(join.getField(),
  79. join.getClazz()), join.getType());
  80. }
  81. }
  82. if (predicateModel == null
  83. || (predicateModel.getFieldName() == null && !predicateModel
  84. .hasSubPredicateModel())) {
  85. // 无查询条件
  86. return cb.conjunction();
  87. }
  88. return toPredicateFromModel(predicateModel, root, cb);
  89. }
  90. @SuppressWarnings({ "unchecked", "rawtypes" })
  91. private Predicate toPredicateFromModel(PredicateModel pm, Root<T> root,
  92. CriteriaBuilder cb) {
  93. if (pm.hasSubPredicateModel()) {// 处理下级模型
  94. List<Predicate> predicateList = new ArrayList<Predicate>();
  95. for (PredicateModel p : pm.getSubPms()) {
  96. predicateList.add(toPredicateFromModel(p, root, cb));
  97. }
  98. Predicate[] predicates = new Predicate[predicateList.size()];
  99. predicateList.toArray(predicates);
  100. switch (pm.getJoinType()) {
  101. case AND:
  102. return cb.and(predicates);
  103. case OR:
  104. return cb.or(predicates);
  105. default:
  106. return cb.and(predicates);
  107. }
  108. } else {// 无下级模型时
  109. // nested path translate, 如Task的名为"user.name"的filedName,
  110. // 转换为Task.user.name属性
  111. String[] names = StringUtils.split(pm.getFieldName(), ".");
  112. Path expression = root.get(names[0]);
  113. for (int i = 1; i < names.length; i++) {
  114. expression = expression.get(names[i]);
  115. }
  116. // logic operator
  117. switch (pm.getOperator()) {
  118. case IN:
  119. In in = cb.in(expression);
  120. Iterable<?> it = (Iterable<?>) pm.getValue();
  121. for (Object o : it) {
  122. in.value(o);
  123. }
  124. return in;
  125. case EQ:
  126. return cb.equal(expression, pm.getValue());
  127. case NEQ:
  128. return cb.notEqual(expression, pm.getValue());
  129. case LIKE:
  130. return cb.like(expression.as(String.class), "%" + pm.getValue() + "%");
  131. case LIKE_L:
  132. return cb.like(expression.as(String.class), "%" + pm.getValue());
  133. case LIKE_R:
  134. return cb.like(expression.as(String.class), pm.getValue() + "%");
  135. case GT:
  136. return cb.greaterThan(expression,
  137. (Comparable) pm.getValue());
  138. case LT:
  139. return cb.lessThan(expression, (Comparable) pm.getValue());
  140. case GTE:
  141. return cb.greaterThanOrEqualTo(expression,
  142. (Comparable) pm.getValue());
  143. case LTE:
  144. return cb.lessThanOrEqualTo(expression,
  145. (Comparable) pm.getValue());
  146. case NL:
  147. return cb.isNull(expression);
  148. case NNL:
  149. return cb.isNotNull(expression);
  150. default:
  151. return cb.equal(expression, pm.getValue());
  152. }
  153. }
  154. }
  155. }
  156. }