扩展Specification(新)

    xiaoxiao2022-07-13  164

    import lombok.Getter; import lombok.Setter; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang.StringUtils; import org.springframework.data.domain.Sort; import org.springframework.data.jpa.domain.Specification; import javax.persistence.criteria.*; import java.util.ArrayList; import java.util.Collection; import java.util.List; /** * @Author: Ma Chi * @Date: 2019-05-22 * @Time: 16:05 * @ClassName: McSpecification * @Description: 扩展Specification */ public class McSpecification<T> implements Specification<T> { /** * 属性分隔符 */ private static final String PROPERTY_SEPARATOR = "."; /** * and条件组 */ List<Cnd> andConditions = new ArrayList<>(); /** * or条件组 */ List<Cnd> orConditions = new ArrayList<>(); /** * 排序条件组 */ List<Order> orders = new ArrayList<>(); @Override public Predicate toPredicate(Root<T> 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; } /** * 给里面传参,用Cnd里面得静态方法,可以传多个值 * * @param conditions * @return */ public McSpecification and(Cnd... conditions) { for (Cnd condition : conditions) { //循环全部添加到and条件组 andConditions.add(condition); } return this; } public McSpecification or(Collection<Cnd> conditions) { //全添加到or条件组 orConditions.addAll(conditions); return this; } public McSpecification desc(String property) { this.orders.add(Order.desc(property)); return this; } public McSpecification asc(String property) { this.orders.add(Order.asc(property)); return this; } /** * 把and条件组得拼到一起 * * @param root * @param cb * @return */ private Predicate getAndPredicates(Root<T> root, CriteriaBuilder cb) { //过滤条件用Predicate方法拼接 Predicate restrictions = cb.conjunction(); for (Cnd 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) { /** * isAssignableFrom()方法是判断是否为某个类的父类,父类.class.isAssignableFrom(子类.class) * instanceof关键字是判断是否某个类的子类。子类实例 instanceof 父类类型 */ if (String.class.isAssignableFrom(path.getJavaType()) && condition.value instanceof String) { if (!((String) condition.value).isEmpty()) {//判断condition.value 是否有元素 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) { if (!((String) condition.value).isEmpty()) {//判断condition.value 是否有元素 restrictions = cb.and(restrictions, cb.ge((Path<Number>) path, (Number) condition.value)); } } break; case gt://大于 if (Number.class.isAssignableFrom(path.getJavaType()) && condition.value instanceof Number) { if (!((String) condition.value).isEmpty()) {//判断condition.value 是否有元素 restrictions = cb.and(restrictions, cb.gt((Path<Number>) path, (Number) condition.value)); } } break; case le://小于等于 if (Number.class.isAssignableFrom(path.getJavaType()) && condition.value instanceof Number) { if (!((String) condition.value).isEmpty()) {//判断condition.value 是否有元素 restrictions = cb.and(restrictions, cb.le((Path<Number>) path, (Number) condition.value)); } } break; case lt://小于 if (Number.class.isAssignableFrom(path.getJavaType()) && condition.value instanceof Number) { if (!((String) condition.value).isEmpty()) {//判断condition.value 是否有元素 restrictions = cb.and(restrictions, cb.lt((Path<Number>) 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)); } } break; case isNotNull: restrictions = cb.and(restrictions, path.isNotNull()); break; } } return restrictions; } private Predicate getOrPredicates(Root<T> root, CriteriaBuilder cb) { Predicate restrictions = cb.conjunction(); for (Cnd 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) { /** * isAssignableFrom()方法是判断是否为某个类的父类,父类.class.isAssignableFrom(子类.class) * instanceof关键字是判断是否某个类的子类。子类实例 instanceof 父类类型 */ if (String.class.isAssignableFrom(path.getJavaType()) && condition.value instanceof String) { if (!((String) condition.value).isEmpty()) {//判断condition.value 是否有元素 restrictions = cb.or(restrictions, cb.equal(path, condition.value)); } } else { restrictions = cb.or(restrictions, cb.equal(path, condition.value)); } } break; case ge://大于等于 if (Number.class.isAssignableFrom(path.getJavaType()) && condition.value instanceof Number) { if (!((String) condition.value).isEmpty()) {//判断condition.value 是否有元素 restrictions = cb.or(restrictions, cb.ge((Path<Number>) path, (Number) condition.value)); } } break; case gt://大于 if (Number.class.isAssignableFrom(path.getJavaType()) && condition.value instanceof Number) { if (!((String) condition.value).isEmpty()) {//判断condition.value 是否有元素 restrictions = cb.or(restrictions, cb.gt((Path<Number>) path, (Number) condition.value)); } } break; case le://小于等于 if (Number.class.isAssignableFrom(path.getJavaType()) && condition.value instanceof Number) { if (!((String) condition.value).isEmpty()) {//判断condition.value 是否有元素 restrictions = cb.or(restrictions, cb.le((Path<Number>) path, (Number) condition.value)); } } break; case lt://小于 if (Number.class.isAssignableFrom(path.getJavaType()) && condition.value instanceof Number) { if (!((String) condition.value).isEmpty()) {//判断condition.value 是否有元素 restrictions = cb.or(restrictions, cb.lt((Path<Number>) 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)); } } break; case isNotNull: restrictions = cb.or(restrictions, path.isNotNull()); break; } } return restrictions; } /** * 排序 * * @param root * @param cb * @return */ private List<javax.persistence.criteria.Order> getOrders(Root<T> root, CriteriaBuilder cb) { List<javax.persistence.criteria.Order> orderList = new ArrayList<>(); //CollectionUtils.isEmpty判断集合是否为空 if (orderList == 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; } } return orderList; } /** * 获取path * * @param path * @param propertyPath 属性路径 * @param <X> * @return Path */ private <X> Path<X> getPath(Path<X> path, String propertyPath) { if (path == null || StringUtils.isEmpty(propertyPath)) { return (Path<X>) path; } //StringUtils.substringBefore 截取指定字符串(PROPERTY_SEPARATOR)之前的内容 String property = StringUtils.substringBefore(propertyPath, PROPERTY_SEPARATOR); //StringUtils.substringAfter 截取指定字符串(PROPERTY_SEPARATOR)之后的内容 return getPath(path.get(property), StringUtils.substringAfter(propertyPath, PROPERTY_SEPARATOR)); } /** * 条件 */ public static class Cnd { Operator operator;//运算符 String property;//属性 Object value;//值 public Cnd(Operator operator, String property, Object value) { this.operator = operator; this.property = property; this.value = value; } /** * 相等 * * @param property 属性 * @param value 值 * @return */ public static Cnd eq(String property, Object value) { return new Cnd(Operator.eq, property, value); } /** * 不相等 * * @param property 属性 * @param value 值 * @return */ public static Cnd ne(String property, Object value) { return new Cnd(Operator.ne, property, value); } /** * 大于 * * @param property 属性 * @param value 值 * @return */ public static Cnd gt(String property, Object value) { return new Cnd(Operator.gt, property, value); } /** * 小于 * * @param property 属性 * @param value 值 * @return */ public static Cnd lt(String property, Object value) { return new Cnd(Operator.lt, property, value); } /** * 大于等于 * * @param property 属性 * @param value 值 * @return */ public static Cnd ge(String property, Object value) { return new Cnd(Operator.ge, property, value); } /** * 小于等于 * * @param property 属性 * @param value 值 * @return */ public static Cnd le(String property, Object value) { return new Cnd(Operator.le, property, value); } /** * 不为null * * @param property 属性 * @param value 值 * @return */ public static Cnd isNotNull(String property, Object value) { return new Cnd(Operator.isNotNull, property, value); } } /** * 运算符 */ public enum Operator { /** * 等于 */ eq("="), /** * 不等于 */ ne(" != "), /** * 大于 */ gt(">"), /** * 小于 */ lt("<"), /** * 大于等于 */ ge(">="), /** * 小于等于 */ le("<="), /** * 不为null */ isNotNull(" is not Null"); @Getter @Setter private String operator; Operator(String operator) { this.operator = operator; } } /** * 排序 */ @Getter @Setter public static class Order { private String property;//属性 private Sort.Direction direction = Sort.Direction.ASC;//方向 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); } } }
    最新回复(0)