SPring boot jpa 封装查询条件

Stella981
• 阅读 635

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

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

Java代码   SPring boot jpa 封装查询条件

  1. /**

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

  3. * @author lee

  4. *

  5. * @param 

  6. */

  7. public class Criteria implements Specification{

  8.     private List criterions = new ArrayList();

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

  10.             CriteriaBuilder builder) {  

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

  12.             List predicates = new ArrayList();

  13.             for(Criterion c : criterions){

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

  15.             }  

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

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

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

  19.             }  

  20.         }  

  21.         return builder.conjunction();

  22.     }  

  23.     /**

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

  25. * @Methods Name add

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

  27. * @param expression0 void

  28. */

  29.     public void add(Criterion criterion){

  30.         if(criterion!=null){

  31.             criterions.add(criterion);  

  32.         }  

  33.     }  

  34. }

  

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

Java代码   SPring boot jpa 封装查询条件

  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代码   SPring boot jpa 封装查询条件

  1. /**

  2. * 简单条件表达式

  3. * @author lee

  4. *

  5. */

  6. public class SimpleExpression implements Criterion{

  7.     private String fieldName;       //属性名

  8.     private Object value;           //对应值

  9.     private Operator operator;      //计算符

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

  11.         this.fieldName = fieldName;

  12.         this.value = value;

  13.         this.operator = operator;

  14.     }  

  15.     public String getFieldName() {

  16.         return fieldName;

  17.     }  

  18.     public Object getValue() {

  19.         return value;

  20.     }  

  21.     public Operator getOperator() {

  22.         return operator;

  23.     }  

  24.     @SuppressWarnings({ "rawtypes", "unchecked" })

  25.     public Predicate toPredicate(Root root, CriteriaQuery query,

  26.             CriteriaBuilder builder) {  

  27.         Path expression = null;

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

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

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

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

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

  33.             }  

  34.         }else{

  35.             expression = root.get(fieldName);  

  36.         }  

  37.         switch (operator) {

  38.         case EQ:

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

  40.         case NE:

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

  42.         case LIKE:

  43.             return builder.like((Expression) expression, "%" + value + "%");

  44.         case LT:

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

  46.         case GT:

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

  48.         case LTE:

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

  50.         case GTE:

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

  52.         default:

  53.             return null;

  54.         }  

  55.     }  

  56. }

  

 一个逻辑条件计算实现

Java代码   SPring boot jpa 封装查询条件

  1. /**

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

  3. * @author lee

  4. *

  5. */

  6. public class LogicalExpression implements Criterion {

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

  8.     private Operator operator;      //计算符

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

  10.         this.criterion = criterions;

  11.         this.operator = operator;

  12.     }  

  13.     public Predicate toPredicate(Root root, CriteriaQuery query,

  14.             CriteriaBuilder builder) {  

  15.         List predicates = new ArrayList();

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

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

  18.         }  

  19.         switch (operator) {

  20.         case OR:

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

  22.         default:

  23.             return null;

  24.         }  

  25.     }  

  26. }

  

 添加一个组装工厂类

Java代码   SPring boot jpa 封装查询条件

  1. /**

  2. * 条件构造器

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

  4. * @Class Name Restrictions

  5. * @Author lee

  6. */

  7. public class Restrictions {

  8.     /**

  9. * 等于

  10. * @param fieldName

  11. * @param value

  12. * @param ignoreNull

  13. * @return

  14. */

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

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

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

  18.     }  

  19.     /**

  20. * 不等于

  21. * @param fieldName

  22. * @param value

  23. * @param ignoreNull

  24. * @return

  25. */

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

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

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

  29.     }  

  30.     /**

  31. * 模糊匹配

  32. * @param fieldName

  33. * @param value

  34. * @param ignoreNull

  35. * @return

  36. */

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

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

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

  40.     }  

  41.     /**

  42. *

  43. * @param fieldName

  44. * @param value

  45. * @param matchMode

  46. * @param ignoreNull

  47. * @return

  48. */

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

  50.             MatchMode matchMode, boolean ignoreNull) {

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

  52.         return null;

  53.     }  

  54.     /**

  55. * 大于

  56. * @param fieldName

  57. * @param value

  58. * @param ignoreNull

  59. * @return

  60. */

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

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

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

  64.     }  

  65.     /**

  66. * 小于

  67. * @param fieldName

  68. * @param value

  69. * @param ignoreNull

  70. * @return

  71. */

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

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

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

  75.     }  

  76.     /**

  77. * 大于等于

  78. * @param fieldName

  79. * @param value

  80. * @param ignoreNull

  81. * @return

  82. */

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

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

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

  86.     }  

  87.     /**

  88. * 小于等于

  89. * @param fieldName

  90. * @param value

  91. * @param ignoreNull

  92. * @return

  93. */

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

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

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

  97.     }  

  98.     /**

  99. * 并且

  100. * @param criterions

  101. * @return

  102. */

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

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

  105.     }  

  106.     /**

  107. * 或者

  108. * @param criterions

  109. * @return

  110. */

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

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

  113.     }  

  114.     /**

  115. * 包含于

  116. * @param fieldName

  117. * @param value

  118. * @return

  119. */

  120.     @SuppressWarnings("rawtypes")

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

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

  123.             return null;

  124.         }  

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

  126.         int i=0;

  127.         for(Object obj : value){

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

  129.             i++;  

  130.         }  

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

  132.     }  

  133. }

  

 使用方法如下

Java代码   SPring boot jpa 封装查询条件

  1. Criteria c = new Criteria();
  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的接口类

 原文:http://lee1177.iteye.com/blog/1994295

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Wesley13 Wesley13
3年前
java将前端的json数组字符串转换为列表
记录下在前端通过ajax提交了一个json数组的字符串,在后端如何转换为列表。前端数据转化与请求varcontracts{id:'1',name:'yanggb合同1'},{id:'2',name:'yanggb合同2'},{id:'3',name:'yang
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
4个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Stella981 Stella981
3年前
Android So动态加载 优雅实现与原理分析
背景:漫品Android客户端集成适配转换功能(基于目标识别(So库35M)和人脸识别库(5M)),导致apk体积50M左右,为优化客户端体验,决定实现So文件动态加载.!(https://oscimg.oschina.net/oscnet/00d1ff90e4b34869664fef59e3ec3fdd20b.png)点击上方“蓝字”关注我
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
3年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
10个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这