最近使用spring data jpa做了两个项目,对于动态查询的不友好做了个类似hibernate的封装,记录也分享下
首先定义一个所有条件的容器,继承Specification
/** * 定义一个查询条件容器 * @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);
其中eventDao为继承JpaSpecificationExecutor的接口类
相关推荐
Spring Data JPA 是Spring基于ORM框架、JPA规范封装的...学习并使用SpringDataJPA可以极大提高开发效率! 除了CRUD外,还包括如分页、排序等一些常用的功能。下面的示例代码即可完成数据保存的操作,而无需具体实现类.
Spring Data 是 Spring 的一个子...2:详解Spring Data JPA封装的各种查询方式 3:详解Spring Data JPA常用接口 4:详解Spring Data JPA各种查询方式 5:详解Spring Data JPA在web方面的用法 具体内容,可以参考大纲:
springdatajpa让数据访问更轻便,直接封装数据访问的代码,简化代码编写.不需要写sql语句,也不需要配置维护关系的xml文件,直接调用底层方法就能实现数据库的增删改查,功能堪称完美
多表查询在spring data jpa中有两种实现方式,第一种是利用hibernate的级联查询来实现,第二种是创建一个结果集的接口来接收连表查询后的结果,这里介绍第二种方式,小编觉得挺不错的,现在分享给大家,也给大家做个...
Spring-data-jpa:spring-data-jpa的封装及源代码解析
• 服务层,封装复杂业务逻辑 • UserService类、StatusService类 • 控制层,Controller,URL路径映射 • UserController类、FriendshipController类、StatusController类、 CommentController类、...
实现JPA基本数据库操作功能封装 实现基于ASM9,动态生成entity、repository、service、serviceImpl、controller相关.class 可根据库表,一键生成新增、修改删除、查询等接口 实现部分基于mybatis-plus,动态代码生成...
Spring Data JPA 是 Spring 基于 ORM 框架、JPA 规范的基础上封装的一套JPA应用框架,可使开发者用极简的代码即可实现对数据的访问和操作。这篇文章主要介绍了Spring-boot中使用Spring-data-jpa方便快捷的访问数据库...
SpringData提供了针对数据库(包括SQL和NOSQL)的整合方案,对Hibernate JPA、Jedis等工具的api进行高级的封装,为我们提供简单方便地操作接口。 Spring Data JPA Spring Data提供了针对数据库(包括SQL和NOSQL)的...
Spring Data 项目的目的是为了简化构建基于 Spring 框架应用的数据访问计数,包括非关系数据库、Map-Reduce 框架、云数据服务等等;另外也包含对关系数据库的访问支持。Spring Data 包含多个子项目:Commons - 提供...
对数据库的操作无非就“增删改查”。就最为普遍的单表操作而言,除了表和字段不同外,语句都是类似的,开发人员需要写...Spring-data-jpa的出现正可以让这样一个已经很“薄”的数据访问层变成只是一层接口的编写方式。
Spring Data JPA 是 Spring 基于 ORM 框架、JPA 规范的基础上封装的一套JPA应用框架,可使开发者用极简的代码即可实现对数据库的访问和操作。它提供了包括增删改查等在内的常用功能,且易于扩展!学习并使用 Spring ...
Spring Data JPA 是 Spring 基于 ORM 框架、JPA 规范的基础上封装的一套JPA应用框架,可使开发者用极简的代码即可实现对数据的访问和操作,本文给大家详细介绍了Spring Boot JPA如何把ORM统一起来,感兴趣的朋友一起...
Spring Data 项目的目的是为了简化构建基于 Spring 框架应用的数据访问计数,包括非关系数据库、Map-Reduce 框架、云数据服务等等;另外也包含对关系数据库的访问支持。 Spring Data 包含多个子项目: Commons - ...
3、系统中对springdata的查询条件Specification做了简单的封装,更加方便查询条件的灵活使用。 4、前端技术:使用Hadmin系统模版,数据表格使用bootstrap table插件,弹窗使用layer插件,日期选择使用laydate插件。...
BootDo-JPA是在SpringBoot基础上搭建的一个Java基础开发平台,SpringDataJPA为数据访问层,ApacheShiro为权限授权层,Ehcahe对常用数据进行缓存。 BootDo-JPA主要定位于后台管理系统学习交流,已内置后台管理系统的...
系统中对springdata的查询条件Specification做了简单的封装,更加方便查询条件的灵活使用。 前端技术:使用Hadmin系统模版,数据表格使用bootstrap table插件,弹窗使用layer插件,日期选择使用laydate插件。表单...
3、系统中对springdata的查询条件Specification做了简单的封装,更加方便查询条件的灵活使用。 4、前端技术:使用Hadmin系统模版,数据表格使用bootstrap table插件,弹窗使用layer插件,日期选择使用laydate插件。...
封装hibernate查询方式(JPA)
iOS中的timer的循环引用问题,对timer进行了一次封装