欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

spring data jpa的动态查询封装

程序员文章站 2022-07-16 18:31:04
...
最近使用spring data jpa做了两个项目,对于动态查询的不友好做了个类似hibernate的封装,记录也分享下
首先定义一个所有条件的容器,继承Specification
/**
* 定义一个查询条件容器
* @author lee
*
* @param <T>
*/ 
public class Criteria<T> implements Specification<T>{ 
    private List<Criterion> criterions = new ArrayList<Criterion>(); 
 
    public Predicate toPredicate(Root<T> root, CriteriaQuery<?> query, 
            CriteriaBuilder builder) { 
        if (!criterions.isEmpty()) { 
            List<Predicate> predicates = new ArrayList<Predicate>(); 
            for(Criterion c : criterions){ 
                predicates.add(c.toPredicate(root, query,builder)); 
            } 
            // 将所有条件用 and 联合起来 
            if (predicates.size() > 0) { 
                return builder.and(predicates.toArray(new Predicate[predicates.size()])); 
            } 
        } 
        return builder.conjunction(); 
    } 
    /**
     * 增加简单条件表达式
     * @Methods Name add
     * @Create In 2012-2-8 By lee
     * @param expression0 void
     */ 
    public void add(Criterion criterion){ 
        if(criterion!=null){ 
            criterions.add(criterion); 
        } 
    } 

然后是各种条件组装类,我首先做了一个接口来包装各种条件
Java代码  收藏代码
/**
* 条件接口
* 用户提供条件表达式接口
* @Class Name Criterion
* @Author lee
* @Create In 2012-2-8
*/ 
public interface Criterion { 
    public enum Operator { 
        EQ, NE, LIKE, GT, LT, GTE, LTE, AND, OR 
    } 
    public Predicate toPredicate(Root<?> root, CriteriaQuery<?> query, 
            CriteriaBuilder builder); 

然后是针对不同类型条件处理的实现
一个是简单比较类型的处理

Java代码  收藏代码
/**
* 简单条件表达式
* @author lee
*
*/ 
public class SimpleExpression implements Criterion{ 
     
    private String fieldName;       //属性名 
    private Object value;           //对应值 
    private Operator operator;      //计算符 
 
    protected SimpleExpression(String fieldName, Object value, Operator operator) { 
        this.fieldName = fieldName; 
        this.value = value; 
        this.operator = operator; 
    } 
 
    public String getFieldName() { 
        return fieldName; 
    } 
    public Object getValue() { 
        return value; 
    } 
    public Operator getOperator() { 
        return operator; 
    } 
    @SuppressWarnings({ "rawtypes", "unchecked" }) 
    public Predicate toPredicate(Root<?> root, CriteriaQuery<?> query, 
            CriteriaBuilder builder) { 
        Path expression = null; 
        if(fieldName.contains(".")){ 
            String[] names = StringUtils.split(fieldName, "."); 
            expression = root.get(names[0]); 
            for (int i = 1; i < names.length; i++) { 
                expression = expression.get(names[i]); 
            } 
        }else{ 
            expression = root.get(fieldName); 
        } 
         
        switch (operator) { 
        case EQ: 
            return builder.equal(expression, value); 
        case NE: 
            return builder.notEqual(expression, value); 
        case LIKE: 
            return builder.like((Expression<String>) expression, "%" + value + "%"); 
        case LT: 
            return builder.lessThan(expression, (Comparable) value); 
        case GT: 
            return builder.greaterThan(expression, (Comparable) value); 
        case LTE: 
            return builder.lessThanOrEqualTo(expression, (Comparable) value); 
        case GTE: 
            return builder.greaterThanOrEqualTo(expression, (Comparable) value); 
        default: 
            return null; 
        } 
    } 
     

一个逻辑条件计算实现
Java代码  收藏代码
/**
* 逻辑条件表达式 用于复杂条件时使用,如但属性多对应值的OR查询等
* @author lee
*
*/ 
public class LogicalExpression implements Criterion { 
    private Criterion[] criterion;  // 逻辑表达式中包含的表达式 
    private Operator operator;      //计算符 
 
    public LogicalExpression(Criterion[] criterions, Operator operator) { 
        this.criterion = criterions; 
        this.operator = operator; 
    } 
 
    public Predicate toPredicate(Root<?> root, CriteriaQuery<?> query, 
            CriteriaBuilder builder) { 
        List<Predicate> predicates = new ArrayList<Predicate>(); 
        for(int i=0;i<this.criterion.length;i++){ 
            predicates.add(this.criterion[i].toPredicate(root, query, builder)); 
        } 
        switch (operator) { 
        case OR: 
            return builder.or(predicates.toArray(new Predicate[predicates.size()])); 
        default: 
            return null; 
        } 
    } 
 

添加一个组装工厂类
Java代码  收藏代码
/**
* 条件构造器
* 用于创建条件表达式
* @Class Name Restrictions
* @Author lee
*/ 
public class Restrictions { 
 
    /**
     * 等于
     * @param fieldName
     * @param value
     * @param ignoreNull
     * @return
     */ 
    public static SimpleExpression eq(String fieldName, Object value, boolean ignoreNull) { 
        if(StringUtils.isEmpty(value))return null; 
        return new SimpleExpression (fieldName, value, Operator.EQ); 
    } 
     
    /**
     * 不等于
     * @param fieldName
     * @param value
     * @param ignoreNull
     * @return
     */ 
    public static SimpleExpression ne(String fieldName, Object value, boolean ignoreNull) { 
        if(StringUtils.isEmpty(value))return null; 
        return new SimpleExpression (fieldName, value, Operator.NE); 
    } 
 
    /**
     * 模糊匹配
     * @param fieldName
     * @param value
     * @param ignoreNull
     * @return
     */ 
    public static SimpleExpression like(String fieldName, String value, boolean ignoreNull) { 
        if(StringUtils.isEmpty(value))return null; 
        return new SimpleExpression (fieldName, value, Operator.LIKE); 
    } 
 
    /**
     * 
     * @param fieldName
     * @param value
     * @param matchMode
     * @param ignoreNull
     * @return
     */ 
    public static SimpleExpression like(String fieldName, String value, 
            MatchMode matchMode, boolean ignoreNull) { 
        if(StringUtils.isEmpty(value))return null; 
        return null; 
    } 
 
    /**
     * 大于
     * @param fieldName
     * @param value
     * @param ignoreNull
     * @return
     */ 
    public static SimpleExpression gt(String fieldName, Object value, boolean ignoreNull) { 
        if(StringUtils.isEmpty(value))return null; 
        return new SimpleExpression (fieldName, value, Operator.GT); 
    } 
 
    /**
     * 小于
     * @param fieldName
     * @param value
     * @param ignoreNull
     * @return
     */ 
    public static SimpleExpression lt(String fieldName, Object value, boolean ignoreNull) { 
        if(StringUtils.isEmpty(value))return null; 
        return new SimpleExpression (fieldName, value, Operator.LT); 
    } 
 
    /**
     * 大于等于
     * @param fieldName
     * @param value
     * @param ignoreNull
     * @return
     */ 
    public static SimpleExpression lte(String fieldName, Object value, boolean ignoreNull) { 
        if(StringUtils.isEmpty(value))return null; 
        return new SimpleExpression (fieldName, value, Operator.GTE); 
    } 
 
    /**
     * 小于等于
     * @param fieldName
     * @param value
     * @param ignoreNull
     * @return
     */ 
    public static SimpleExpression gte(String fieldName, Object value, boolean ignoreNull) { 
        if(StringUtils.isEmpty(value))return null; 
        return new SimpleExpression (fieldName, value, Operator.LTE); 
    } 
 
    /**
     * 并且
     * @param criterions
     * @return
     */ 
    public static LogicalExpression and(Criterion... criterions){ 
        return new LogicalExpression(criterions, Operator.AND); 
    } 
    /**
     * 或者
     * @param criterions
     * @return
     */ 
    public static LogicalExpression or(Criterion... criterions){ 
        return new LogicalExpression(criterions, Operator.OR); 
    } 
    /**
     * 包含于
     * @param fieldName
     * @param value
     * @return
     */ 
    @SuppressWarnings("rawtypes") 
    public static LogicalExpression in(String fieldName, Collection value, boolean ignoreNull) { 
        if(ignoreNull&&(value==null||value.isEmpty())){ 
            return null; 
        } 
        SimpleExpression[] ses = new SimpleExpression[value.size()]; 
        int i=0; 
        for(Object obj : value){ 
            ses[i]=new SimpleExpression(fieldName,obj,Operator.EQ); 
            i++; 
        } 
        return new LogicalExpression(ses,Operator.OR); 
    } 

使用方法如下
Java代码  收藏代码
Criteria<Event> c = new Criteria<Event>(); 
c.add(Restrictions.like("code", searchParam.getCode(), true)); 
        c.add(Restrictions.eq("level", searchParam.getLevel(), false)); 
        c.add(Restrictions.eq("mainStatus", searchParam.getMainStatus(), true)); 
        c.add(Restrictions.eq("flowStatus", searchParam.getFlowStatus(), true)); 
        c.add(Restrictions.eq("createUser.userName", searchParam.getCreateUser(), true)); 
        c.add(Restrictions.lte("submitTime", searchParam.getStartSubmitTime(), true)); 
        c.add(Restrictions.gte("submitTime", searchParam.getEndSubmitTime(), true)); 
        c.add(Restrictions.eq("needFollow", searchParam.getIsfollow(), true)); 
        c.add(Restrictions.ne("flowStatus", CaseConstants.CASE_STATUS_DRAFT, true)); 
        c.add(Restrictions.in("solveTeam.code",teamCodes, true)); 
eventDao.findAll(c); 
其中eventDao为继承JpaSpecificationExecutor的接口类
相关标签: jpa spring