spring data jpa的动态查询封装

阅读更多
最近使用spring data jpa做了两个项目,对于动态查询的不友好做了个类似hibernate的封装,记录也分享下
首先定义一个所有条件的容器,继承Specification
/**
* 定义一个查询条件容器
* @author lee
*
* @param
*/ 
public class Criteria implements Specification
    private List criterions = new ArrayList(); 
 
    public Predicate toPredicate(Root root, CriteriaQuery query, 
            CriteriaBuilder builder) { 
        if (!criterions.isEmpty()) { 
            List predicates = new ArrayList(); 
            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) 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 predicates = new ArrayList(); 
        for(int i=0;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 c = new Criteria(); 
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)