/**
* 定义一个查询条件容器
* @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. Java基础学习笔记二十二 网络编程

    络通信协议 通过计算机网络可以使多台计算机实现连接,位于同一个网络中的计算机在进行连接和通信时需要遵守一定的规则,这就好比在道路中行驶的汽车一定要遵守交通规则一样.在计算机网络中,这些连接和通信的规则 ...

  2. Hibernate——配置并访问数据库

    Hibernate,对于java来说很重要的一个东西,用于持久层.之前看了很多配置的,都不行,自己来写一个配置成功的. 环境:jdk1.8,eclipse-jee-oxygen,mysql-conne ...

  3. 设置linux虚拟机的固定ip、防火墙的一些操作

    安装好虚拟机后,需要设置其固定ip,这样才可以连接该虚拟服务器 设置步骤如下 1.进入network-scripts目录 cd /etc/sysconfig/network-scripts 2.编辑n ...

  4. Beta第二天

    听说

  5. HTTP协议以及HTTP2.0/1.1/1.0区别

    HTTP协议以及HTTP2.0/1.1/1.0区别 一.简介 摘自百度百科: 超文本传输协议(HTTP,HyperText Transfer Protocol)是互联网上应用最为广泛的一种网络协议.所 ...

  6. 《javascript设计模式与开发实践》阅读笔记(13)—— 职责链模式

    职责链模式 使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系,将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止. 书里的订单的例子 假设我们负责一个售卖手机 ...

  7. 14-TypeScript简单工厂模式

    在TypeScript中,要调用功能,通常在调用方通过实例化被调用方对象来调用相关方法,但这种实现在调用方和被调用方形成了强耦合的关系. 另外如果被调用方有种实现,在调用方需要根据场景去实例化不同的类 ...

  8. Win10下, TortoiseGit安装及配合Gitee使用完整版

    Windows10下, TortoiseGit的安装及使用, 并配合Gitee码云使用! 1) 安装TortoiseGit 官网, 32位, 64位, 自选 https://tortoisegit.o ...

  9. redis入门(02)redis的常见问题

    一.常见问题 1.安装遇到/bin/sh: cc: command not found 解决办法:安装gcc yum install gcc 2.后台启动server端 2.1.问题现象 2.2.解决 ...

  10. HTTP协议扫盲(六)InputStream的复用

    一.问题提出 在进行网关引擎开发时,获取到一个http请求的inputstream后,可能要多次利用它进行read操作.由于流读过一次就不能再读了,所以需要实现InputStream的复制. 而Inp ...