当前位置 : 主页 > 编程语言 > java >

MySpecification Jpa复杂条件查询封装

来源:互联网 收集:自由互联 发布时间:2021-06-28
MySpecification package import org.apache.commons.lang3.StringUtils;import org.springframework.data.domain.Sort;import org.springframework.data.jpa.domain.Specification;import org.springframework.util.CollectionUtils;import javax.persistenc
MySpecification
package 

import org.apache.commons.lang3.StringUtils;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.util.CollectionUtils;

import javax.persistence.criteria.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;

/**
 * Created By mx1014 On 17-11-23
 *
 * @author Mx1014
 * 使用示例 
 * PageRequest pr = new PageRequest(0, 10);
 * Page pageData = userDao.findAll(new MySpecification
 
  ().and(
 * QueryParams.like("id", id),
 * QueryParams.like("Name",Name)).asc("id"), pr);
 */
public class MySpecification
  
    implements Specification
   
     { //属性分隔 private static final String PROPERTY_SEPARATOR = "."; //AND List
    
      andConditions = new ArrayList<>(); //OR List
     
       orConditions = new ArrayList<>(); //排序 List
      
        orders = new ArrayList<>(); @Override public Predicate toPredicate(Root
       
         root, CriteriaQuery
         cq, CriteriaBuilder cb) { Predicate restrictions = cb.and(getAndPredicates(root, cb)); restrictions = cb.and(restrictions, getOrPredicates(root, cb)); cq.orderBy(getOrders(root, cb)); return restrictions; } public MySpecification and(Collection
        
          conditions) { andConditions.addAll(conditions); return this; } public MySpecification and(QueryParams... conditions) { for (QueryParams condition : conditions) { andConditions.add(condition); } return this; } public MySpecification or(Collection
         
           conditions) { orConditions.addAll(conditions); return this; } public MySpecification or(QueryParams... conditions) { for (QueryParams condition : conditions) { orConditions.add(condition); } return this; } public MySpecification desc(String property) { this.orders.add(Order.desc(property)); return this; } public MySpecification asc(String property) { this.orders.add(Order.asc(property)); return this; } public MySpecification order(String property, Sort.Direction direction) { this.orders.add(new Order(property, direction)); return this; } public MySpecification orders(Order... orders) { this.orders.addAll(Arrays.asList(orders)); return this; } public MySpecification orders(Collection
          
            orders) { this.orders.addAll(orders); return this; } private Predicate getAndPredicates(Root
           
             root, CriteriaBuilder cb) { Predicate restrictions = cb.conjunction(); for (QueryParams condition : andConditions) { if (condition == null) { continue; } Path
             path = this.getPath(root, condition.property); if (path == null) { continue; } switch (condition.operator) { case eq: if (condition.value != null) { if (String.class.isAssignableFrom(path.getJavaType()) && condition.value instanceof String) { if (!((String) condition.value).isEmpty()) { restrictions = cb.and(restrictions, cb.equal(path, condition.value)); } } else { restrictions = cb.and(restrictions, cb.equal(path, condition.value)); } } break; case ge: if (Number.class.isAssignableFrom(path.getJavaType()) && condition.value instanceof Number) { restrictions = cb.and(restrictions, cb.ge((Path
            
             ) path, (Number) condition.value)); } break; case gt: if (Number.class.isAssignableFrom(path.getJavaType()) && condition.value instanceof Number) { restrictions = cb.and(restrictions, cb.gt((Path
             
              ) path, (Number) condition.value)); } break; case in: restrictions = cb.and(restrictions, path.in(condition.value)); break; case le: if (Number.class.isAssignableFrom(path.getJavaType()) && condition.value instanceof Number) { restrictions = cb.and(restrictions, cb.le((Path
              
               ) path, (Number) condition.value)); } break; case lt: if (Number.class.isAssignableFrom(path.getJavaType()) && condition.value instanceof Number) { restrictions = cb.and(restrictions, cb.lt((Path
               
                ) path, (Number) condition.value)); } break; case ne: if (condition.value != null) { if (String.class.isAssignableFrom(path.getJavaType()) && condition.value instanceof String && !((String) condition.value).isEmpty()) { restrictions = cb.and(restrictions, cb.notEqual(path, condition.value)); } else { restrictions = cb.and(restrictions, cb.notEqual(path, condition.value)); } } break; case like: if (condition.value != null) { if (String.class.isAssignableFrom(path.getJavaType()) && condition.value instanceof String && !((String) condition.value).isEmpty()) { restrictions = cb.and(restrictions, cb.like((Path
                
                 ) path, "%" + condition.value + "%")); } } break; case ilike: if (condition.value != null) { if (String.class.isAssignableFrom(path.getJavaType()) && condition.value instanceof String && !((String) condition.value).isEmpty()) { restrictions = cb.and(restrictions, cb.like((Path
                 
                  ) path, (String) condition.value)); } } break; case llike: if (condition.value != null) { if (String.class.isAssignableFrom(path.getJavaType()) && condition.value instanceof String && !((String) condition.value).isEmpty()) { restrictions = cb.and(restrictions, cb.like((Path
                  
                   ) path, "%" + condition.value)); } } break; case rlike: if (condition.value != null) { if (String.class.isAssignableFrom(path.getJavaType()) && condition.value instanceof String && !((String) condition.value).isEmpty()) { restrictions = cb.and(restrictions, cb.like((Path
                   
                    ) path, condition.value + "%")); } } break; case notIn: restrictions = cb.and(restrictions, path.in(condition.value).not()); break; case isNull: restrictions = cb.and(restrictions, path.isNull()); break; case isNotNull: restrictions = cb.and(restrictions, path.isNotNull()); break; default: break; } } return restrictions; } private Predicate getOrPredicates(Root
                    
                      root, CriteriaBuilder cb) { Predicate restrictions = cb.conjunction(); for (QueryParams condition : orConditions) { if (condition == null) { continue; } Path
                      path = this.getPath(root, condition.property); if (path == null) { continue; } switch (condition.operator) { case eq: if (condition.value != null) { if (String.class.isAssignableFrom(path.getJavaType()) && condition.value instanceof String) { if (!((String) condition.value).isEmpty()) { restrictions = cb.or(restrictions, cb.equal(path, condition.value)); } } } else { restrictions = cb.or(restrictions, path.isNull()); } break; case ge: if (Number.class.isAssignableFrom(path.getJavaType()) && condition.value instanceof Number) { restrictions = cb.or(restrictions, cb.ge((Path
                     
                      ) path, (Number) condition.value)); } break; case gt: if (Number.class.isAssignableFrom(path.getJavaType()) && condition.value instanceof Number) { restrictions = cb.or(restrictions, cb.gt((Path
                      
                       ) path, (Number) condition.value)); } break; case in: restrictions = cb.or(restrictions, path.in(condition.value)); break; case le: if (Number.class.isAssignableFrom(path.getJavaType()) && condition.value instanceof Number) { restrictions = cb.or(restrictions, cb.le((Path
                       
                        ) path, (Number) condition.value)); } break; case lt: if (Number.class.isAssignableFrom(path.getJavaType()) && condition.value instanceof Number) { restrictions = cb.or(restrictions, cb.lt((Path
                        
                         ) path, (Number) condition.value)); } break; case ne: if (condition.value != null) { if (String.class.isAssignableFrom(path.getJavaType()) && condition.value instanceof String && !((String) condition.value).isEmpty()) { restrictions = cb.or(restrictions, cb.notEqual(path, condition.value)); } else { restrictions = cb.or(restrictions, cb.notEqual(path, condition.value)); } } break; case like: if (condition.value != null) { if (String.class.isAssignableFrom(path.getJavaType()) && condition.value instanceof String && !((String) condition.value).isEmpty()) { restrictions = cb.or(restrictions, cb.like((Path
                         
                          ) path, "%" + condition.value + "%")); } } break; case ilike: if (condition.value != null) { if (String.class.isAssignableFrom(path.getJavaType()) && condition.value instanceof String && !((String) condition.value).isEmpty()) { restrictions = cb.or(restrictions, cb.like((Path
                          
                           ) path, (String) condition.value)); } } break; case llike: if (condition.value != null) { if (String.class.isAssignableFrom(path.getJavaType()) && condition.value instanceof String && !((String) condition.value).isEmpty()) { restrictions = cb.or(restrictions, cb.like((Path
                           
                            ) path, "%" + condition.value)); } } break; case rlike: if (condition.value != null) { if (String.class.isAssignableFrom(path.getJavaType()) && condition.value instanceof String && !((String) condition.value).isEmpty()) { restrictions = cb.or(restrictions, cb.like((Path
                            
                             ) path, condition.value + "%")); } } break; case notIn: restrictions = cb.or(restrictions, path.in(condition.value).not()); break; case isNull: restrictions = cb.or(restrictions, path.isNull()); break; case isNotNull: restrictions = cb.or(restrictions, path.isNotNull()); break; default: break; } } return restrictions; } private List
                             
                               getOrders(Root
                              
                                root, CriteriaBuilder cb) { List
                               
                                 orderList = new ArrayList<>(); if (root == null || CollectionUtils.isEmpty(orders)) { return orderList; } for (Order order : orders) { if (order == null) { continue; } String property = order.getProperty(); Sort.Direction direction = order.getDirection(); Path
                                 path = this.getPath(root, property); if (path == null || direction == null) { continue; } switch (direction) { case ASC: orderList.add(cb.asc(path)); break; case DESC: orderList.add(cb.desc(path)); break; default: break; } } return orderList; } /** * 获取Path * * @param path Path * @param propertyPath 属性路径 * @return Path */ private 
                                
                                  Path
                                 
                                   getPath(Path
                                   path, String propertyPath) { if (path == null || StringUtils.isEmpty(propertyPath)) { return (Path
                                  
                                   ) path; } String property = StringUtils.substringBefore(propertyPath, PROPERTY_SEPARATOR); return getPath(path.get(property), StringUtils.substringAfter(propertyPath, PROPERTY_SEPARATOR)); } /** * 运算符 */ public enum Operator { /** * 等于 */ eq(" = "), /** * 不等于 */ ne(" != "), /** * 大于 */ gt(" > "), /** * 小于 */ lt(" < "), /** * 大于等于 */ ge(" >= "), /** * 小于等于 */ le(" <= "), /** * 类似 */ like(" like "), /** * 类似 */ rlike("like "), /** * 类似 */ llike(" like "), /** * 类似 */ ilike(" like "), /** * 包含 */ in(" in "), /** * 包含 */ notIn(" not in "), /** * 为Null */ isNull(" is NULL "), /** * 不为Null */ isNotNull(" is not NULL "); private String operator; Operator(String operator) { this.operator = operator; } public String getOperator() { return operator; } public void setOperator(String operator) { this.operator = operator; } } /** * 条件 */ public static class QueryParams { Operator operator; String property; Object value; public QueryParams(String property, Operator operator, Object value) { this.operator = operator; this.property = property; this.value = value; } public QueryParams(String property, Operator operator) { this.operator = operator; this.property = property; } /** * 相等 * * @param property * @param value * @return */ public static QueryParams eq(String property, Object value) { return new QueryParams(property, Operator.eq, value); } /** * 不相等 * * @param property * @param value * @return */ public static QueryParams ne(String property, Object value) { return new QueryParams(property, Operator.ne, value); } /** * 大于 * * @param property * @param value * @return */ public static QueryParams gt(String property, Object value) { return new QueryParams(property, Operator.gt, value); } /** * 小于 * * @param property * @param value * @return */ public static QueryParams lt(String property, Object value) { return new QueryParams(property, Operator.lt, value); } /** * 大于等于 * * @param property * @param value * @return */ public static QueryParams ge(String property, Object value) { return new QueryParams(property, Operator.ge, value); } /** * 小于等于 * * @param property * @param value * @return */ public static QueryParams le(String property, Object value) { return new QueryParams(property, Operator.le, value); } /** * like %% * * @param property * @param value * @return */ public static QueryParams like(String property, Object value) { return new QueryParams(property, Operator.like, value); } /** * 右like xxx% * * @param property * @param value * @return */ public static QueryParams rlike(String property, Object value) { return new QueryParams(property, Operator.rlike, value); } /** *左like %xxx * * @param property * @param value * @return */ public static QueryParams llike(String property, Object value) { return new QueryParams(property, Operator.llike, value); } /** * 自定义模糊 * * @param property * @param value * @return */ public static QueryParams ilike(String property, Object value) { return new QueryParams(property, Operator.ilike, value); } /** * 集合中 * * @param property * @param value * @return */ public static QueryParams in(String property, Object value) { return new QueryParams(property, Operator.in, value); } /** * 不在集合中 * * @param property * @param value * @return */ public static QueryParams notIn(String property, Object value) { return new QueryParams(property, Operator.notIn, value); } /** * 是空 * * @param property * @return */ public static QueryParams isNull(String property) { return new QueryParams(property, Operator.isNull); } /** * 不是空 * * @param property * @return */ public static QueryParams isNotNull(String property) { return new QueryParams(property, Operator.isNotNull); } } /** * 排序 */ public static class Order { private String property; private Sort.Direction direction = Sort.Direction.ASC; /** * 构造方法 */ public Order() { } /** * 构造方法 * * @param property 属性 * @param direction 方向 */ public Order(String property, Sort.Direction direction) { this.property = property; this.direction = direction; } /** * 返回递增排序 * * @param property 属性 * @return 递增排序 */ public static Order asc(String property) { return new Order(property, Sort.Direction.ASC); } /** * 返回递减排序 * * @param property 属性 * @return 递减排序 */ public static Order desc(String property) { return new Order(property, Sort.Direction.DESC); } @Override public String toString() { return property + " " + direction.name(); } public Sort.Direction getDirection() { return direction; } public String getProperty() { return property; } } }
                                  
                                 
                                
                               
                              
                             
                            
                           
                          
                         
                        
                       
                      
                     
                    
                   
                  
                 
                
               
              
             
            
           
          
         
        
       
      
     
    
   
  
 
网友评论