zoukankan      html  css  js  c++  java
  • spring data jpa的动态查询封装(转)

    最近使用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的接口类

    最近使用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的接口类

  • 相关阅读:
    在SQL Server中使用NewID()随机取得某行
    委托和事件:第 3 页 事件的由来
    case when then else 详解
    spring-boot-starter-security Spring Boot中集成Spring Security
    spring-boot-actuator健康监控
    汉字转拼音开源工具包Jpinyin介绍
    JAVA实现汉字转换为拼音 pinyin4j/JPinyin
    Spring MVC 后端接口支持跨域CORS调用
    web开发-CORS支持
    maven POM.xml 标签详解
  • 原文地址:https://www.cnblogs.com/quanfu2326/p/4290714.html
Copyright © 2011-2022 走看看