springdata中Specification查询封装

1、操作符类:

package net.sppan.base.service.specification;
/**
 * 操作符类,这个类中存储了键值对和操作符号,另外存储了连接下一个条件的类型是and还是or
 * 
* 创建时通过 id>=7,其中id就是key,>=就是oper操作符,7就是value *
* 特殊的自定义几个操作符(:表示like %v%,b:表示v%,:b表示%v) */ public class SpecificationOperator { /** * 操作符的key,如查询时的name,id之类 */ private String key; /** * 操作符的value,具体要查询的值 */ private Object value; /** * 操作符,自己定义的一组操作符,用来方便查询 */ private String oper; /** * 连接的方式:and或者or */ private String join; public String getKey() { return key; } public void setKey(String key) { this.key = key; } public Object getValue() { return value; } public void setValue(Object value) { this.value = value; } public String getOper() { return oper; } public void setOper(String oper) { this.oper = oper; } public String getJoin() { return join; } public void setJoin(String join) { this.join = join; } public static enum Operator { eq, ge, le, gt, lt, likeL, likeR, likeAll, isNull, isNotNull, notEqual; @Override public String toString() { return name(); } } public static enum Join { and, or; @Override public String toString() { return name(); } } }

Specification实现类:

package net.sppan.base.service.specification;
import net.sppan.base.service.specification.SpecificationOperator.Join;
import org.springframework.data.jpa.domain.Specification;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.List;
public class SimpleSpecification implements Specification {
    /**
     * 查询的条件列表,是一组列表
     * */
    private List opers;
    public SimpleSpecification(List opers) {
        this.opers = opers;
    }
    @Override
    public Predicate toPredicate(Root root, CriteriaQuery criteriaQuery, CriteriaBuilder criteriaBuilder) {
        int index = 0;
        //通过resultPre来组合多个条件
        Predicate resultPre = null;
        for(SpecificationOperator op:opers) {
            if(index++==0) {
                resultPre = generatePredicate(root,criteriaBuilder,op);
                continue;
            }
            Predicate pre = generatePredicate(root,criteriaBuilder,op);
            if(pre==null) continue;
            if(Join.and.name().equalsIgnoreCase(op.getJoin())) {
                resultPre = criteriaBuilder.and(resultPre,pre);
            } else if(Join.or.name().equalsIgnoreCase(op.getJoin())) {
                resultPre = criteriaBuilder.or(resultPre,pre);
            }
        }
        return resultPre;
    }
    private Predicate generatePredicate(Root root,CriteriaBuilder criteriaBuilder, SpecificationOperator op) {
        /*
        * 根据不同的操作符返回特定的查询*/
        if(SpecificationOperator.Operator.eq.name().equalsIgnoreCase(op.getOper())) {
            return criteriaBuilder.equal(root.get(op.getKey()),op.getValue());
        } else if(SpecificationOperator.Operator.ge.name().equalsIgnoreCase(op.getOper())) {
            return criteriaBuilder.ge(root.get(op.getKey()).as(Number.class), (Number)op.getValue());
        } else if(SpecificationOperator.Operator.le.name().equalsIgnoreCase(op.getOper())) {
            return criteriaBuilder.le(root.get(op.getKey()).as(Number.class),(Number)op.getValue());
        } else if(SpecificationOperator.Operator.gt.name().equalsIgnoreCase(op.getOper())) {
            return criteriaBuilder.gt(root.get(op.getKey()).as(Number.class),(Number)op.getValue());
        } else if(SpecificationOperator.Operator.lt.name().equalsIgnoreCase(op.getOper())) {
            return criteriaBuilder.lt(root.get(op.getKey()).as(Number.class),(Number)op.getValue());
        } else if(SpecificationOperator.Operator.likeAll.name().equalsIgnoreCase(op.getOper())) {
            return criteriaBuilder.like(root.get(op.getKey()).as(String.class),"%"+op.getValue()+"%");
        } else if(SpecificationOperator.Operator.likeL.name().equalsIgnoreCase(op.getOper())) {
            return criteriaBuilder.like(root.get(op.getKey()).as(String.class),op.getValue()+"%");
        } else if(SpecificationOperator.Operator.likeR.name().equalsIgnoreCase(op.getOper())) {
            return criteriaBuilder.like(root.get(op.getKey()).as(String.class),"%"+op.getValue());
        } else if(SpecificationOperator.Operator.isNull.name().equalsIgnoreCase(op.getOper())) {
            return criteriaBuilder.isNull(root.get(op.getKey()));
        } else if(SpecificationOperator.Operator.isNotNull.name().equalsIgnoreCase(op.getOper())) {
            return criteriaBuilder.isNotNull(root.get(op.getKey()));
        } else if(SpecificationOperator.Operator.notEqual.name().equalsIgnoreCase(op.getOper())) {
            return criteriaBuilder.notEqual(root.get(op.getKey()),op.getValue());
        }
        return null;
    }
}

查询条件构造类:

package net.sppan.base.service.specification;
import java.util.ArrayList;
import java.util.List;
import net.sppan.base.service.specification.SpecificationOperator.Join;
import org.springframework.data.jpa.domain.Specification;
public class SimpleSpecificationBuilder {
    /**
     * 条件列表
     */
    private List opers;
    /**
     * 构造函数,初始化的条件是and
     */
    public SimpleSpecificationBuilder(String key,String oper,Object value) {
        SpecificationOperator so = new SpecificationOperator();
        so.setJoin(Join.and.name());
        so.setKey(key);
        so.setOper(oper);
        so.setValue(value);
        opers = new ArrayList();
        opers.add(so);
    }
    public SimpleSpecificationBuilder() {
        opers = new ArrayList();
    }
    /**
     * 完成条件的添加
     * @return
     */
    public SimpleSpecificationBuilder add(String key,String oper,Object value,String join) {
        SpecificationOperator so = new SpecificationOperator();
        so.setKey(key);
        so.setValue(value);
        so.setOper(oper);
        so.setJoin(join);
        opers.add(so);
        return this;
    }
    /**
     * 添加or条件的重载
     * @return this,方便后续的链式调用
     */
    public SimpleSpecificationBuilder addOr(String key,String oper,Object value) {
        return this.add(key,oper,value,Join.or.name());
    }
    /**
     * 添加and的条件
     * @return
     */
    public SimpleSpecificationBuilder add(String key,String oper,Object value) {
        return this.add(key,oper,value,Join.and.name());
    }
    public Specification generateSpecification() {
        Specification specification = new SimpleSpecification(opers);
        return specification;
    }
}

使用方式:

SimpleSpecificationBuilder builder = new SimpleSpecificationBuilder();//Resource 持久层实体
builder.add("name", Operator.likeAll.name(), "keyword");
Specification specification = builder.generateSpecification()

你可能感兴趣的:(springdata中Specification查询封装)