spring data jpa 模仿hibernate,进行动态查询封装 Specification

最近使用spring data jpa做了两个项目,对于动态查询的不友好做了个类似hibernate的封装,记录也分享下

首先定义一个所有条件的容器,继承Specification

Java代码  收藏代码

  1. /** 

  2.  * 定义一个查询条件容器 

  3.  * @author lee 

  4.  * 

  5.  * @param <T> 

  6.  */  

  7. public class Criteria<T> implements Specification<T>{  

  8.     private List<Criterion> criterions = new ArrayList<Criterion>();  

  9.   

  10.     public Predicate toPredicate(Root<T> root, CriteriaQuery<?> query,  

  11.             CriteriaBuilder builder) {  

  12.         if (!criterions.isEmpty()) {  

  13.             List<Predicate> predicates = new ArrayList<Predicate>();  

  14.             for(Criterion c : criterions){  

  15.                 predicates.add(c.toPredicate(root, query,builder));  

  16.             }  

  17.             // 将所有条件用 and 联合起来  

  18.             if (predicates.size() > 0) {  

  19.                 return builder.and(predicates.toArray(new Predicate[predicates.size()]));  

  20.             }  

  21.         }  

  22.         return builder.conjunction();  

  23.     }  

  24.     /** 

  25.      * 增加简单条件表达式 

  26.      * @Methods Name add 

  27.      * @Create In 2012-2-8 By lee 

  28.      * @param expression0 void 

  29.      */  

  30.     public void add(Criterion criterion){  

  31.         if(criterion!=null){  

  32.             criterions.add(criterion);  

  33.         }  

  34.     }  

  35. }  

 然后是各种条件组装类,我首先做了一个接口来包装各种条件

Java代码  收藏代码

  1. /** 

  2.  * 条件接口 

  3.  * 用户提供条件表达式接口 

  4.  * @Class Name Criterion 

  5.  * @Author lee 

  6.  * @Create In 2012-2-8 

  7.  */  

  8. public interface Criterion {  

  9.     public enum Operator {  

  10.         EQ, NE, LIKE, GT, LT, GTE, LTE, AND, OR  

  11.     }  

  12.     public Predicate toPredicate(Root<?> root, CriteriaQuery<?> query,  

  13.             CriteriaBuilder builder);  

  14. }  

 然后是针对不同类型条件处理的实现

一个是简单比较类型的处理

 

Java代码  收藏代码

  1. /** 

  2.  * 简单条件表达式 

  3.  * @author lee 

  4.  * 

  5.  */  

  6. public class SimpleExpression implements Criterion{  

  7.       

  8.     private String fieldName;       //属性名  

  9.     private Object value;           //对应值  

  10.     private Operator operator;      //计算符  

  11.   

  12.     protected SimpleExpression(String fieldName, Object value, Operator operator) {  

  13.         this.fieldName = fieldName;  

  14.         this.value = value;  

  15.         this.operator = operator;  

  16.     }  

  17.   

  18.     public String getFieldName() {  

  19.         return fieldName;  

  20.     }  

  21.     public Object getValue() {  

  22.         return value;  

  23.     }  

  24.     public Operator getOperator() {  

  25.         return operator;  

  26.     }  

  27.     @SuppressWarnings({ "rawtypes""unchecked" })  

  28.     public Predicate toPredicate(Root<?> root, CriteriaQuery<?> query,  

  29.             CriteriaBuilder builder) {  

  30.         Path expression = null;  

  31.         if(fieldName.contains(".")){  

  32.             String[] names = StringUtils.split(fieldName, ".");  

  33.             expression = root.get(names[0]);  

  34.             for (int i = 1; i < names.length; i++) {  

  35.                 expression = expression.get(names[i]);  

  36.             }  

  37.         }else{  

  38.             expression = root.get(fieldName);  

  39.         }  

  40.           

  41.         switch (operator) {  

  42.         case EQ:  

  43.             return builder.equal(expression, value);  

  44.         case NE:  

  45.             return builder.notEqual(expression, value);  

  46.         case LIKE:  

  47.             return builder.like((Expression<String>) expression, "%" + value + "%");  

  48.         case LT:  

  49.             return builder.lessThan(expression, (Comparable) value);  

  50.         case GT:  

  51.             return builder.greaterThan(expression, (Comparable) value);  

  52.         case LTE:  

  53.             return builder.lessThanOrEqualTo(expression, (Comparable) value);  

  54.         case GTE:  

  55.             return builder.greaterThanOrEqualTo(expression, (Comparable) value);  

  56.         default:  

  57.             return null;  

  58.         }  

  59.     }  

  60.       

  61. }  

 一个逻辑条件计算实现

Java代码  收藏代码

  1. /** 

  2.  * 逻辑条件表达式 用于复杂条件时使用,如但属性多对应值的OR查询等 

  3.  * @author lee 

  4.  * 

  5.  */  

  6. public class LogicalExpression implements Criterion {  

  7.     private Criterion[] criterion;  // 逻辑表达式中包含的表达式  

  8.     private Operator operator;      //计算符  

  9.   

  10.     public LogicalExpression(Criterion[] criterions, Operator operator) {  

  11.         this.criterion = criterions;  

  12.         this.operator = operator;  

  13.     }  

  14.   

  15.     public Predicate toPredicate(Root<?> root, CriteriaQuery<?> query,  

  16.             CriteriaBuilder builder) {  

  17.         List<Predicate> predicates = new ArrayList<Predicate>();  

  18.         for(int i=0;i<this.criterion.length;i++){  

  19.             predicates.add(this.criterion[i].toPredicate(root, query, builder));  

  20.         }  

  21.         switch (operator) {  

  22.         case OR:  

  23.             return builder.or(predicates.toArray(new Predicate[predicates.size()]));  

  24.         default:  

  25.             return null;  

  26.         }  

  27.     }  

  28.   

  29. }  

 添加一个组装工厂类

Java代码  收藏代码

  1. /** 

  2.  * 条件构造器 

  3.  * 用于创建条件表达式 

  4.  * @Class Name Restrictions 

  5.  * @Author lee 

  6.  */  

  7. public class Restrictions {  

  8.   

  9.     /** 

  10.      * 等于 

  11.      * @param fieldName 

  12.      * @param value 

  13.      * @param ignoreNull 

  14.      * @return 

  15.      */  

  16.     public static SimpleExpression eq(String fieldName, Object value, boolean ignoreNull) {  

  17.         if(StringUtils.isEmpty(value))return null;  

  18.         return new SimpleExpression (fieldName, value, Operator.EQ);  

  19.     }  

  20.       

  21.     /** 

  22.      * 不等于 

  23.      * @param fieldName 

  24.      * @param value 

  25.      * @param ignoreNull 

  26.      * @return 

  27.      */  

  28.     public static SimpleExpression ne(String fieldName, Object value, boolean ignoreNull) {  

  29.         if(StringUtils.isEmpty(value))return null;  

  30.         return new SimpleExpression (fieldName, value, Operator.NE);  

  31.     }  

  32.   

  33.     /** 

  34.      * 模糊匹配 

  35.      * @param fieldName 

  36.      * @param value 

  37.      * @param ignoreNull 

  38.      * @return 

  39.      */  

  40.     public static SimpleExpression like(String fieldName, String value, boolean ignoreNull) {  

  41.         if(StringUtils.isEmpty(value))return null;  

  42.         return new SimpleExpression (fieldName, value, Operator.LIKE);  

  43.     }  

  44.   

  45.     /** 

  46.      *  

  47.      * @param fieldName 

  48.      * @param value 

  49.      * @param matchMode 

  50.      * @param ignoreNull 

  51.      * @return 

  52.      */  

  53.     public static SimpleExpression like(String fieldName, String value,  

  54.             MatchMode matchMode, boolean ignoreNull) {  

  55.         if(StringUtils.isEmpty(value))return null;  

  56.         return null;  

  57.     }  

  58.   

  59.     /** 

  60.      * 大于 

  61.      * @param fieldName 

  62.      * @param value 

  63.      * @param ignoreNull 

  64.      * @return 

  65.      */  

  66.     public static SimpleExpression gt(String fieldName, Object value, boolean ignoreNull) {  

  67.         if(StringUtils.isEmpty(value))return null;  

  68.         return new SimpleExpression (fieldName, value, Operator.GT);  

  69.     }  

  70.   

  71.     /** 

  72.      * 小于 

  73.      * @param fieldName 

  74.      * @param value 

  75.      * @param ignoreNull 

  76.      * @return 

  77.      */  

  78.     public static SimpleExpression lt(String fieldName, Object value, boolean ignoreNull) {  

  79.         if(StringUtils.isEmpty(value))return null;  

  80.         return new SimpleExpression (fieldName, value, Operator.LT);  

  81.     }  

  82.   

  83.     /** 

  84.      * 大于等于 

  85.      * @param fieldName 

  86.      * @param value 

  87.      * @param ignoreNull 

  88.      * @return 

  89.      */  

  90.     public static SimpleExpression lte(String fieldName, Object value, boolean ignoreNull) {  

  91.         if(StringUtils.isEmpty(value))return null;  

  92.         return new SimpleExpression (fieldName, value, Operator.GTE);  

  93.     }  

  94.   

  95.     /** 

  96.      * 小于等于 

  97.      * @param fieldName 

  98.      * @param value 

  99.      * @param ignoreNull 

  100.      * @return 

  101.      */  

  102.     public static SimpleExpression gte(String fieldName, Object value, boolean ignoreNull) {  

  103.         if(StringUtils.isEmpty(value))return null;  

  104.         return new SimpleExpression (fieldName, value, Operator.LTE);  

  105.     }  

  106.   

  107.     /** 

  108.      * 并且 

  109.      * @param criterions 

  110.      * @return 

  111.      */  

  112.     public static LogicalExpression and(Criterion... criterions){  

  113.         return new LogicalExpression(criterions, Operator.AND);  

  114.     }  

  115.     /** 

  116.      * 或者 

  117.      * @param criterions 

  118.      * @return 

  119.      */  

  120.     public static LogicalExpression or(Criterion... criterions){  

  121.         return new LogicalExpression(criterions, Operator.OR);  

  122.     }  

  123.     /** 

  124.      * 包含于 

  125.      * @param fieldName 

  126.      * @param value 

  127.      * @return 

  128.      */  

  129.     @SuppressWarnings("rawtypes")  

  130.     public static LogicalExpression in(String fieldName, Collection value, boolean ignoreNull) {  

  131.         if(ignoreNull&&(value==null||value.isEmpty())){  

  132.             return null;  

  133.         }  

  134.         SimpleExpression[] ses = new SimpleExpression[value.size()];  

  135.         int i=0;  

  136.         for(Object obj : value){  

  137.             ses[i]=new SimpleExpression(fieldName,obj,Operator.EQ);  

  138.             i++;  

  139.         }  

  140.         return new LogicalExpression(ses,Operator.OR);  

  141.     }  

  142. }  

 使用方法如下

Java代码  收藏代码

  1. Criteria<Event> c = new Criteria<Event>();  

  2. c.add(Restrictions.like("code", searchParam.getCode(), true));  

  3.         c.add(Restrictions.eq("level", searchParam.getLevel(), false));  

  4.         c.add(Restrictions.eq("mainStatus", searchParam.getMainStatus(), true));  

  5.         c.add(Restrictions.eq("flowStatus", searchParam.getFlowStatus(), true));  

  6.         c.add(Restrictions.eq("createUser.userName", searchParam.getCreateUser(), true));  

  7.         c.add(Restrictions.lte("submitTime", searchParam.getStartSubmitTime(), true));  

  8.         c.add(Restrictions.gte("submitTime", searchParam.getEndSubmitTime(), true));  

  9.         c.add(Restrictions.eq("needFollow", searchParam.getIsfollow(), true));  

  10.         c.add(Restrictions.ne("flowStatus", CaseConstants.CASE_STATUS_DRAFT, true));  

  11.         c.add(Restrictions.in("solveTeam.code",teamCodes, true));  

  12. eventDao.findAll(c);  

 其中eventDao为继承JpaSpecificationExecutor的接口类


转载于:https://my.oschina.net/u/2471041/blog/526504

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值