spring data jpa 组合条件查询封装
/**
* 定义一个查询条件容器
* @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);
}
}
}
然后是各种条件组装类,我首先做了一个接口来包装各种条件
/**
* 条件接口
* 用户提供条件表达式接口
* @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 组合条件查询封装的更多相关文章
- 【Spring Data 系列学习】Spring Data JPA @Query 注解查询
[Spring Data 系列学习]Spring Data JPA @Query 注解查询 前面的章节讲述了 Spring Data Jpa 通过声明式对数据库进行操作,上手速度快简单易操作.但同时 ...
- Spring data jpa 复杂动态查询方式总结
一.Spring data jpa 简介 首先我并不推荐使用jpa作为ORM框架,毕竟对于负责查询的时候还是不太灵活,还是建议使用mybatis,自己写sql比较好.但是如果公司用这个就没办法了,可以 ...
- Spring data JPA 理解(默认查询 自定义查询 分页查询)及no session 三种处理方法
简介:Spring Data JPA 其实就是JDK方式(还有一种cglib的方式需要Class)的动态代理 (需要一个接口 有一大堆接口最上边的是Repository接口来自org.springfr ...
- spring data jpa 多对多查询
package com.ytkj.dao; import com.ytkj.entity.Customer; import com.ytkj.entity.Role; import org.sprin ...
- spring data jpa 一对多查询
在一对多关系中,我们习惯把一的一方称之为主表,把多的一方称之为从表.在数据库中建立一对多的关系,需要使用数据库的外键约束. 什么是外键? 指的是从表中有一列,取值参照主表的主键,这一列就是外键. pa ...
- Spring Data JPA应用 之查询分析
在Spring Data JPA应用之常规CRUD操作初体验 - 池塘里洗澡的鸭子 - 博客园 (cnblogs.com)尾附上了JpaRepository接口继承关系及方法,可以知道JpaRepos ...
- 记: Spring Data Jpa @OneToMany 级联查询被动触发的问题
I have encountered a bug in using Spring Data Jpa. Specifically,when @OneToMany was used to maintain ...
- spring data jpa Specification动态查询
package com.ytkj.entity; import javax.persistence.*; import java.io.Serializable; /** * @Entity * 作用 ...
- Spring Data Jpa (三)定义查询方法
本章详细讲解如何利用方法名定义查询方法(Defining Query Methods) (1)定义查询方法的配置方法 由于Spring JPA Repository的实现原理是采用动态代理的机制,所以 ...
随机推荐
- 在CentOS7.1上安装Gitlab碰到的问题及解决方法
一 前言 关于在CentOS7上安装Gitlab, 官方文档已经很详细了,步骤大家按照官方的安装文档一步一步安装即可, 这里就不在累述.官方安装文档地址: https://about.gitlab. ...
- Could not create pool connection. The DBMS driver exception was: null, message from server: "Host '192.168.XX.XX' is blocked because of many connection errors; unblock with 'mysqladmin flush-hosts'
早上打开浏览器准备登陆某个系统,发现Error 404--Not Found,有点奇怪,这个服务器应该没人用了才对,然后到weblogic后台去看日志,报如下错误: "Could not c ...
- Beta 第四天
今天遇到的困难: 百度位置假死的问题研究发现并不是源于代码的问题,而是直接运行在主线程中会出现诸多问题 Fragment碎片刷新时总产生的固定位置的问题未果 今天完成的任务: 陈甘霖:修复了部分Bug ...
- Java的HelloWorld程序
Java的HelloWorld程序 1.新建文本文档,编写HelloWorld程序,最后保存时记得保存成.java格式 2.在D盘新建一个HelloJava文件夹用于保存java程序 3.使用WIN+ ...
- bzoj千题计划251:bzoj3672: [Noi2014]购票
http://www.lydsy.com/JudgeOnline/problem.php?id=3672 法一:线段树维护可持久化单调队列维护凸包 斜率优化DP 设dp[i] 表示i号点到根节点的最少 ...
- bzoj千题计划242:bzoj4034: [HAOI2015]树上操作
http://www.lydsy.com/JudgeOnline/problem.php?id=4034 dfs序,树链剖分 #include<cstdio> #include<io ...
- 2017北京国庆刷题Day4 morning
期望得分:0+40+30=70 实际得分:0+10+10=20 题目修改:只能由0变1,只能用一次操作 大模拟 #include<cstdio> #include<cstring&g ...
- 微信支付 chooseWXPay:fail
本来以为解决了微信支付get_brand_wcpay_request:faill这个问题后就万事大吉了,结果又迈入了另一个坑... 问题原因: 1.生成签名的时间戳参数名timestamp的s大小写问 ...
- Mybatis的mapper代理开发dao方法
看完了之前的mybatis原始的dao开发方法是不是觉得有点笨重,甚至说没有发挥mybatis 作为一个框架的优势.总结了一下,原始的dao方法有以下几点不足之处 dao接口实现方法中存在大量的模板方 ...
- python-map的用法
map()函数 map()是 Python 内置的高阶函数,它接收一个函数 f 和一个 list,并通过把函数 f 依次作用在 list 的每个元素上,得到一个新的 list 并返回. 1.当seq只 ...