All Downloads are FREE. Search and download functionalities are using the official Maven repository.

top.springdatajpa.zujijpa.wrapper.SpecificationWrapper Maven / Gradle / Ivy

There is a newer version: 1.0.1
Show newest version
package top.springdatajpa.zujijpa.wrapper;

import lombok.Getter;
import lombok.Setter;

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

/**
 * @author azheng
 * @since 2019/5/7
 */
@Getter
@Setter
public class SpecificationWrapper {

    private Root root;
    private CriteriaQuery query;
    private CriteriaBuilder builder;

    private List predicates = new ArrayList<>();

    private static final String SEPARATOR = ".";

    public SpecificationWrapper(Root root, CriteriaQuery query, CriteriaBuilder builder) {
        this.root = root;
        this.query = query;
        this.builder = builder;
    }

    public SpecificationWrapper or(Consumer> action) {
        return this.newWrapper(false, action);
    }

    public SpecificationWrapper and(Consumer> action) {
        return this.newWrapper(true, action);
    }

    public SpecificationWrapper newWrapper(boolean isConjunction, Consumer> action) {
        SpecificationWrapper specification = new SpecificationWrapper<>(root, query, builder);
        CriteriaBuilder newBuilder = specification.getBuilder();
        Predicate predicate = isConjunction ? newBuilder.conjunction() : newBuilder.disjunction();
        action.accept(specification);
        predicate.getExpressions().addAll(specification.getPredicates()) ;
        predicates.add(predicate);
        return this;
    }

    public SpecificationWrapper isNull(boolean condition, String name) {
        return condition ? this.isNull(name) : this;
    }

    public SpecificationWrapper isNull(String name) {
        return handle(name, e -> this.isNull(e));
    }

    public SpecificationWrapper isNull(Expression x) {
        predicates.add(builder.isNull(x));
        return this;
    }

    public SpecificationWrapper isNotNull(boolean condition, String name) {
        return condition ? this.isNotNull(name) : this;
    }

    public SpecificationWrapper isNotNull(String name) {
        return handle(name, e -> this.isNotNull(e));
    }

    public SpecificationWrapper isNotNull(Expression x) {
        predicates.add(builder.isNotNull(x));
        return this;
    }

    public SpecificationWrapper eq(boolean condition, String name, Object value) {
        return condition ? this.eq(name, value) : this;
    }

    public SpecificationWrapper eq(String name, Object value) {
        return handle(name, e -> this.eq(e, value));
    }

    public SpecificationWrapper eq(Expression x, Object value) {
        predicates.add(builder.equal(x, value));
        return this;
    }

    public SpecificationWrapper ne(boolean condition, String name, Object value) {
        return condition ? this.ne(name, value) : this;
    }

    public SpecificationWrapper ne(String name, Object value) {
        return handle(name, e -> this.ne(e, value));
    }

    public SpecificationWrapper ne(Expression x, Object value) {
        predicates.add(builder.notEqual(x, value));
        return this;
    }

    public SpecificationWrapper like(boolean condition, String name, String value) {
        return condition ? this.like(name, value) : this;
    }

    public SpecificationWrapper like(String name, String value) {
        return handle(name, e -> this.like(e, value));
    }

    public SpecificationWrapper like(Expression path, String value){
        predicates.add(builder.like(path, value));
        return this;
    }

    public SpecificationWrapper startingWith(boolean condition, String name, String value) {
        return condition ? this.startingWith(name, value) : this;
    }

    public SpecificationWrapper startingWith(String name, String value) {
        this.like(name,value+"%");
        return this;
    }

    public SpecificationWrapper endingWith(boolean condition, String name, String value) {
        return condition ? this.endingWith(name, value) : this;
    }

    public SpecificationWrapper endingWith(String name, String value) {
        this.like(name,"%"+value);
        return this;
    }

    public SpecificationWrapper contains(boolean condition, String name, String value) {
        return condition ? this.contains(name, value) : this;
    }

    public SpecificationWrapper contains(String name, String value){
        this.like(name,"%"+value+"%");
        return this;
    }

    public > SpecificationWrapper ge(boolean condition, String name, Y value) {
        return condition ? this.ge(name, value) : this;
    }

    public > SpecificationWrapper ge(String name, Y value) {
        return handle(name, e -> this.ge(e, value));
    }

    public > SpecificationWrapper ge
            (Expression path, Y value) {
        predicates.add(builder.greaterThanOrEqualTo(path, value));
        return this;
    }

    public > SpecificationWrapper le(boolean condition, String name, Y value) {
        return condition ? this.le(name, value) : this;
    }

    public > SpecificationWrapper le(String name, Y value) {
        return handle(name, e -> this.le(e, value));
    }

    public > SpecificationWrapper le
            (Expression path, Y value) {
        predicates.add(builder.lessThanOrEqualTo(path, value));
        return this;
    }

    public > SpecificationWrapper gt(boolean condition, String name, Y value) {
        return condition ? this.gt(name, value) : this;
    }

    public > SpecificationWrapper gt(String name, Y value) {
        return handle(name, e -> this.gt(e, value));
    }

    public > SpecificationWrapper gt
            (Expression path, Y value) {
        predicates.add(builder.greaterThan(path, value));
        return this;
    }

    public > SpecificationWrapper lt(boolean condition, String name, Y value) {
        return condition ? this.lt(name, value) : this;
    }

    public > SpecificationWrapper lt(String name, Y value) {
        return handle(name, e -> this.lt(e, value));
    }

    public > SpecificationWrapper lt
            (Expression path, Y value) {
        predicates.add(builder.lessThan(path, value));
        return this;
    }

    public SpecificationWrapper in(boolean condition, String name, Object... value) {
        return condition ? in(name, value) : this;
    }

    public SpecificationWrapper in(String name, Object... value) {
        return handle(name, e -> this.in(e, value));
    }

    public SpecificationWrapper in(boolean condition, String name, Collection value) {
        return condition ? in(name, value) : this;
    }

    public SpecificationWrapper in(String name, Collection value) {
        return this.in(name, value.toArray());
    }

    public  SpecificationWrapper in(Expression expression, Object... value) {
        predicates.add(expression.in(value));
        return this;
    }

    public SpecificationWrapper notIn(boolean condition, String name, Collection value) {
        return condition ? notIn(name, value) : this;
    }

    public SpecificationWrapper notIn(String name, Collection value) {
        return handle(name, e -> this.notIn(e, value.toArray()));
    }

    public SpecificationWrapper notIn(boolean condition, String name, Object... value) {
        return condition ? notIn(name, value) : this;
    }

    public SpecificationWrapper notIn(String name, Object... value) {
        return handle(name, e -> this.notIn(e, value));
    }

    public  SpecificationWrapper notIn(Expression expression, Object... value) {
        predicates.add(expression.in(value).not());
        return this;
    }

    public > SpecificationWrapper between(boolean condition,
                                                                             String name, Y start, Y end){
        return condition ? between(name, start, end) : this;
    }

    public > SpecificationWrapper between(String name, Y start, Y end){
        return handle(name, e -> this.between(e, start, end));
    }

    public > SpecificationWrapper between(Expression path,
                                                                             Y start, Y end){
        predicates.add(builder.between(path, start, end));
        return this;
    }

    public  Join leftJoin(String fieldName) {
        return root.join(fieldName, JoinType.LEFT);
    }

    private SpecificationWrapper handle(String name, Consumer action) {
        Path path;
        if(name.contains(SEPARATOR)){
            String[] arr = name.split("\\"+SEPARATOR);
            path = this.leftJoin(arr[0]).get(arr[1]);
        }else{
            path = this.root.get(name);
        }
        action.accept(path);
        return this;
    }

}