content: package cn.jbone.common.utils;
  
  import cn.jbone.common.dataobject.SearchConditionDO;
  import cn.jbone.common.dataobject.SearchSortDO;
  import org.apache.commons.lang3.StringUtils;
  import org.springframework.data.domain.Sort;
  import org.springframework.util.CollectionUtils;
  
  import javax.persistence.criteria.CriteriaBuilder;
  import javax.persistence.criteria.Path;
  import javax.persistence.criteria.Predicate;
  import javax.persistence.criteria.Root;
  import java.util.ArrayList;
  import java.util.List;
  
  public class SpecificationUtils<T> {
      /**
       * 构建条件查询
       * @param root p
       * @param criteriaBuilder p
       * @param conditions p
       * @param <T> t
       * @return r
       */
      public static <T> List<Predicate> generatePredicates(Root<T> root, CriteriaBuilder criteriaBuilder, List<SearchConditionDO> conditions){
          if(CollectionUtils.isEmpty(conditions)){
              return null;
          }
  
          List<Predicate> predicates = new ArrayList<Predicate>();
          for (SearchConditionDO condition : conditions){
  
              String filedName = condition.getProperty();
  
              if(StringUtils.isBlank(filedName) || condition.getOperator() == null || condition.getValue() == null){
                  continue;
              }
              //基本数字类型且小于0，不作为查询条件
              if(root.get(filedName).getJavaType().isPrimitive() && (Long.parseLong(condition.getValue().toString())) < 0){
                  continue;
              }
  
              //如果是日期类型，需要做下转换
              boolean isDate = false;
              if (!root.get(filedName).getJavaType().isPrimitive()){
                  String typeName = root.get(filedName).getJavaType().getName();
                  if(typeName.equalsIgnoreCase("java.sql.Timestamp") || typeName.equalsIgnoreCase("java.util.Date")){
                      isDate = true;
                  }
              }
  
              Path<Comparable> expression = root.get(filedName);
              Comparable value = (Comparable)condition.getValue();
              if(isDate){
                  value = DateUtil.getDate(value.toString());
              }
  
              if(SearchConditionDO.Operator.EQUAL == condition.getOperator()){
                  predicates.add(criteriaBuilder.equal(expression,value));
              }else if(SearchConditionDO.Operator.NOT_EQUAL == condition.getOperator()){
                  predicates.add(criteriaBuilder.notEqual(expression,value));
              }else if(SearchConditionDO.Operator.LESS_THAN == condition.getOperator()){
                  predicates.add(criteriaBuilder.lessThan(expression,  value));
              }else if(SearchConditionDO.Operator.LESS_THAN_OR_EQUAL == condition.getOperator()){
                  predicates.add(criteriaBuilder.lessThanOrEqualTo(expression,value));
              }else if(SearchConditionDO.Operator.GREATER_THAN == condition.getOperator()){
                  predicates.add(criteriaBuilder.greaterThan(expression,value));
              }else if(SearchConditionDO.Operator.GREATER_THAN_OR_EQUAL == condition.getOperator()){
                  predicates.add(criteriaBuilder.greaterThanOrEqualTo(expression,value));
              }else if(SearchConditionDO.Operator.LIKE == condition.getOperator()){
                  Path<String> expressionLike = root.get(filedName);
                  Object valueLike = condition.getValue();
                  predicates.add(criteriaBuilder.like(expressionLike,"%" + valueLike + "%"));
              }
          }
  
          return predicates;
      }
  
      /**
       * 构建排序
       * @param sortDOS s
       * @return r
       */
      public static Sort buildSort(List<SearchSortDO> sortDOS){
          Sort sort = null;
          //构建排序
          if(!CollectionUtils.isEmpty(sortDOS)){
              List<Sort.Order> orders = new ArrayList<>();
              for (SearchSortDO sortDO: sortDOS) {
                  Sort.Order order = null;
                  if(sortDO.getDirection() == SearchSortDO.Direction.ASC){
                      order = Sort.Order.asc(sortDO.getProperty());
                  }else{
                      order = Sort.Order.desc(sortDO.getProperty());
                  }
                  orders.add(order);
              }
              sort = Sort.by(orders);
          }else{
              sort = Sort.unsorted();
          }
          return sort;
      }
  }
  