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

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

package top.springdatajpa.zujijpa.wrapper;

import lombok.Getter;
import lombok.Setter;
import top.springdatajpa.zujijpa.utils.SpecificationUtils;

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(Predicate.BooleanOperator.OR, action);
    }

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

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

    public SpecificationWrapper eq(boolean condition, String name, Object data) {
        if(condition){
            this.eq(name, data);
        }
        return this;
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    public > SpecificationWrapper between(String name, Y start, Y end){
        predicates.add(builder.between(root.get(name), start, end));
        return this;
    }

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

    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;
    }

}