/**
* 定义一个查询条件容器
* @author lee
*
* @param <T>
*/
public class Criteria<T> implements Specification<T>{
private List<Criterion> criterions = new ArrayList<Criterion>(); public Predicate toPredicate(Root<T> root, CriteriaQuery<?> query,
CriteriaBuilder builder) {
if (!criterions.isEmpty()) {
List<Predicate> predicates = new ArrayList<Predicate>();
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);
}
}
}

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

  1. /**
    * 条件接口
    * 用户提供条件表达式接口
    * @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);
    }

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

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

/**
* 简单条件表达式
* @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<String>) 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;
}
} }

一个逻辑条件计算实现

/**
* 逻辑条件表达式 用于复杂条件时使用,如但属性多对应值的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<Predicate> predicates = new ArrayList<Predicate>();
for(int i=0;i<this.criterion.length;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;
}
} }

添加一个组装工厂类

/**
* 条件构造器
* 用于创建条件表达式
* @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);
}
}

使用方法如下

Criteria<Event> c = new Criteria<Event>();
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);

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. 集大1513 & 1514班 软件工程第二次作业评分与点评

    谢谢按时完成作业的同学. 请大家在今后的作业中多思考,认真完成并注意作业的原创性. 学号 作业标题 作业地址 提交日期 分数 201521121087 微信APP简要分析 http://www.cnb ...

  2. Alpha第十天

    Alpha第十天 听说 031502543 周龙荣(队长) 031502615 李家鹏 031502632 伍晨薇 031502637 张柽 031502639 郑秦 1.前言 任务分配是VV.ZQ. ...

  3. HASH方法课下补分博客

    课堂要求:利用除留余数法为下列关键字集合的存储设计hash函数,并画出分别用开放寻址法和拉链法解决冲突得到的空间存储状态(散列因子取0.75)关键字集合:85,75,57,60,65,(你的8位学号相 ...

  4. python自动发邮件

    from email.header import Header from email.mime.text import MIMEText from email.utils import parsead ...

  5. Flask学习 三 web表单

    web表单 pip install flask-wtf 实现csrf保护 app.config['SECRET_KEY']='hard to guess string' # 可以用来存储框架,扩展,程 ...

  6. C# reportview 按时间改变行颜色

    //) AND ((Day(Now()) - Day() AND (Day(Now()) - Day()),) AND (Day(Now()) - Day()) OR (Month(Now()) - ...

  7. 微信号的openid的深入理解

    header('Location:https://open.weixin.qq.com/connect/oauth2/authorize?appid='.$this->appid.'&r ...

  8. 到底什么是 "method group"

    class Program { delegate void NoParam(); delegate void WithOneParam(string name); static void Main(s ...

  9. Python内置函数(55)——globals

    英文文档: globals() Return a dictionary representing the current global symbol table. This is always the ...

  10. 新概念英语(1-143)A walk through the woods

    Lesson 143 A walk through the woods 林中散步 Listen to the tape then answer this question. What was so f ...