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. }

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

    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. }

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

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

  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. }

一个逻辑条件计算实现

  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. }

添加一个组装工厂类

  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. }

使用方法如下

  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);

spring data jpa 组合条件查询封装的更多相关文章

  1. 【Spring Data 系列学习】Spring Data JPA @Query 注解查询

    [Spring Data 系列学习]Spring Data JPA @Query 注解查询 前面的章节讲述了 Spring Data Jpa 通过声明式对数据库进行操作,上手速度快简单易操作.但同时 ...

  2. Spring data jpa 复杂动态查询方式总结

    一.Spring data jpa 简介 首先我并不推荐使用jpa作为ORM框架,毕竟对于负责查询的时候还是不太灵活,还是建议使用mybatis,自己写sql比较好.但是如果公司用这个就没办法了,可以 ...

  3. Spring data JPA 理解(默认查询 自定义查询 分页查询)及no session 三种处理方法

    简介:Spring Data JPA 其实就是JDK方式(还有一种cglib的方式需要Class)的动态代理 (需要一个接口 有一大堆接口最上边的是Repository接口来自org.springfr ...

  4. spring data jpa 多对多查询

    package com.ytkj.dao; import com.ytkj.entity.Customer; import com.ytkj.entity.Role; import org.sprin ...

  5. spring data jpa 一对多查询

    在一对多关系中,我们习惯把一的一方称之为主表,把多的一方称之为从表.在数据库中建立一对多的关系,需要使用数据库的外键约束. 什么是外键? 指的是从表中有一列,取值参照主表的主键,这一列就是外键. pa ...

  6. Spring Data JPA应用 之查询分析

    在Spring Data JPA应用之常规CRUD操作初体验 - 池塘里洗澡的鸭子 - 博客园 (cnblogs.com)尾附上了JpaRepository接口继承关系及方法,可以知道JpaRepos ...

  7. 记: Spring Data Jpa @OneToMany 级联查询被动触发的问题

    I have encountered a bug in using Spring Data Jpa. Specifically,when @OneToMany was used to maintain ...

  8. spring data jpa Specification动态查询

    package com.ytkj.entity; import javax.persistence.*; import java.io.Serializable; /** * @Entity * 作用 ...

  9. Spring Data Jpa (三)定义查询方法

    本章详细讲解如何利用方法名定义查询方法(Defining Query Methods) (1)定义查询方法的配置方法 由于Spring JPA Repository的实现原理是采用动态代理的机制,所以 ...

随机推荐

  1. 关于yaml语言

    yaml语言广泛用于书写配置文件. 主要特点如下: 1.使用缩进表示层级关系,缩进使用空格键(非Tab键) 2.缩进的空格数目不要求,只要相同层级的元素左侧对其即可 3.#之后的内容为注释 4.yam ...

  2. machine learning 之 多元线性回归

    整理自Andrew Ng的machine learning课程 week2. 目录: 多元线性回归 Multivariates linear regression /MLR Gradient desc ...

  3. JavaScript(第十一天)【变量,作用域,内存】

    JavaScript的变量与其他语言的变量有很大区别.JavaScript变量是松散型的(不强制类型)本质,决定了它只是在特定时间用于保存特定值的一个名字而已.由于不存在定义某个变量必须要保存何种数据 ...

  4. 实验四 Android程序设计 实验报告

    实验四 Android程序设计 实验报告 目录 代码托管地址 Android程序设计-1 Android程序设计-2 Android程序设计-3 Android程序设计-4 Android程序设计-5 ...

  5. 201621123040《Java程序设计》第十一周学习总结

    1.本周学习总结 1.1以你喜欢的方式(思维导图或其他)归纳总结多线程相关内容. 2.书面作业 2.1源代码阅读:多线程程序BounceThread 2.1.1BallRunnable类有什么用?为什 ...

  6. Django 分类标签查找

    from django.conf.urls import url from django.contrib import admin from blog.views import index,stude ...

  7. ruby:TypeError: 对象不支持此属性或方法

    解决办法. 1.下载对应版本 下载node.js,根据ruby版本决定下载32还是x64,我的ruby版本x64 https://npm.taobao.org/mirrors/node/v8.9.3/ ...

  8. 构建微服务开发环境3————Java应用的优秀管理工具Maven的下载安装及配置

    [内容指引] 下载安装包: MacOS下Maven的安装及配置: Windows下Maven的安装及配置. 一.下载安装包 进入Maven的官方下载地址:http://maven.apache.org ...

  9. 03-移动端开发教程-CSS3新特性(下)

    1. CSS3动画 1.1 过渡的缺点 transition的优点在于简单易用,但是它有几个很大的局限. transition需要事件触发,所以没法在网页加载时自动发生. transition是一次性 ...

  10. Python模块 - os , sys.shutil

    os 模块是与操作系统交互的一个接口 os.getcwd() 获取当前工作目录,即当前python脚本工作的目录路径 os.chdir("dirname") 改变当前脚本工作目录: ...