我们在使用SpringData JPA框架时,进行条件查询,如果是固定条件的查询,我们可以使用符合框架规则的自定义方法以及@Query注解实现。

如果是查询条件是动态的,框架也提供了查询接口。

  1. JpaSpecificationExecutor

和其他接口使用方式一样,只需要在你的Dao接口继承即可(官网代码)。

  1. public interface CustomerRepository extends CrudRepository<Customer, Long>, JpaSpecificationExecutor {

  2. }

JpaSpecificationExecutor提供很多条件查询方法。

  1. public interface JpaSpecificationExecutor<T> {
  2. T findOne(Specification<T> var1);
  3.  
  4. List<T> findAll(Specification<T> var1);
  5.  
  6. Page<T> findAll(Specification<T> var1, Pageable var2);
  7.  
  8. List<T> findAll(Specification<T> var1, Sort var2);
  9.  
  10. long count(Specification<T> var1);
  11. }

比如方法:

  1. List<T> findAll(Specification<T> var1);

就可以查找出符合条件的所有数据,如果你的框架使用的是前段分页的技术,那么这个方法就挺简便的。

那么这个方法该如何使用呢?我们看到它需要的参数是一个

  1. org.springframework.data.jpa.domain.Specification

对象。那我们就创建这个对象先看看。

  1. Specification specification = new Specification() {
  2. @Override
  3. public Predicate toPredicate(Root root, CriteriaQuery criteriaQuery, CriteriaBuilder criteriaBuilder) {
  4. return null;
  5. }
  6. }

IDE自动生成了要重写的方法toPredicate。

root参数是我们用来对应实体的信息的。criteriaBuilder可以帮助我们制作查询信息。

  1. /**
  2. * A root type in the from clause.
  3. * Query roots always reference entities.
  4. *
  5. * @param <X> the entity type referenced by the root
  6. * @since Java Persistence 2.0
  7. */
  8. public interface Root<X> extends From<X, X> {...}
  1. /**
  2. * Used to construct criteria queries, compound selections,
  3. * expressions, predicates, orderings.
  4. *
  5. * <p> Note that <code>Predicate</code> is used instead of <code>Expression<Boolean></code>
  6. * in this API in order to work around the fact that Java
  7. * generics are not compatible with varags.
  8. *
  9. * @since Java Persistence 2.0
  10. */
  11. public interface CriteriaBuilder {...}

CriteriaBuilder对象里有很多条件方法,比如制定条件:某条数据的创建日期小于今天。

  1. criteriaBuilder.lessThan(root.get("createDate"), today)

该方法返回的对象类型是Predicate。正是toPredicate需要返回的值。

如果有多个条件,我们就可以创建一个Predicate集合,最后用CriteriaBuilder的and和or方法进行组合,得到最后的Predicate对象。

  1. /**
  2. * Create a conjunction of the given restriction predicates.
  3. * A conjunction of zero predicates is true.
  4. *
  5. * @param restrictions zero or more restriction predicates
  6. *
  7. * @return and predicate
  8. */
  9. Predicate and(Predicate... restrictions);
  1. /**
  2. * Create a disjunction of the given restriction predicates.
  3. * A disjunction of zero predicates is false.
  4. *
  5. * @param restrictions zero or more restriction predicates
  6. *
  7. * @return or predicate
  8. */
  9. Predicate or(Predicate... restrictions);

示例:

  1. public List<WeChatGzUserInfoEntity> findByCondition(Date minDate, Date maxDate, String nickname){
  2. List<WeChatGzUserInfoEntity> resultList = null;
  3. Specification querySpecifi = new Specification<WeChatGzUserInfoEntity>() {
  4. @Override
  5. public Predicate toPredicate(Root<WeChatGzUserInfoEntity> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
  6.  
  7. List<Predicate> predicates = new ArrayList<>();
  8. if(null != minDate){
  9. predicates.add(criteriaBuilder.greaterThan(root.get("subscribeTime"), minDate));
  10. }
  11. if(null != maxDate){
  12. predicates.add(criteriaBuilder.lessThan(root.get("subscribeTime"), maxDate));
  13. }
  14. if(null != nickname){
  15. predicates.add(criteriaBuilder.like(root.get("nickname"), "%"+nickname+"%"));
  16. }
  17. return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()]));
  18. }
  19. };
  20. resultList = this.weChatGzUserInfoRepository.findAll(querySpecifi);
  21. return resultList;
  22. }

and到一起的话所有条件就是且关系,or就是或关系了。

其实也是在Stack Overflow上看到的。

Spring Data JPA,一种动态条件查询的写法的更多相关文章

  1. 【JPA】Spring Data JPA 实现分页和条件查询

    文章目录 1.在`Repository`层继承两个接口 2.在Service层进行查询操作 3.Page的方法 1.在Repository层继承两个接口 JpaRepository<Admin, ...

  2. Spring Data JPA中的动态查询 时间日期

    功能:Spring Data JPA中的动态查询 实现日期查询 页面对应的dto类private String modifiedDate; //实体类 @LastModifiedDate protec ...

  3. spring data jpa 使用方法命名规则查询

    按照Spring Data JPA 定义的规则,查询方法以findBy开头,涉及条件查询时,条件的属性用条件关键字连接,要注意的是:条件属性首字母需大写.框架在进行方法名解析时,会先把方法名多余的前缀 ...

  4. 【hql】spring data jpa中 @Query使用hql查询 问题

    spring data jpa中 @Query使用hql查询 问题 使用hql查询, 1.from后面跟的是实体类 不是数据表名 2.字段应该用实体类中的字段 而不是数据表中的属性 实体如下 hql使 ...

  5. Spring data jpa 实现简单动态查询的通用Specification方法

    本篇前提: SpringBoot中使用Spring Data Jpa 实现简单的动态查询的两种方法 这篇文章中的第二种方法 实现Specification 这块的方法 只适用于一个对象针对某一个固定字 ...

  6. Spring Data JPA 的 Specifications动态查询

    主要的结构: 有时我们在查询某个实体的时候,给定的条件是不固定的,这时就需要动态构建相应的查询语句,在Spring Data JPA中可以通过JpaSpecificationExecutor接口查询. ...

  7. 使用Spring Data JPA的Specification构建数据库查询

    Spring Data JPA最为优秀的特性就是可以通过自定义方法名称生成查询来轻松创建查询SQL.Spring Data JPA提供了一个Repository编程模型,最简单的方式就是通过扩展Jpa ...

  8. spring data jpa 使用JPQL的方式查询

    用Spring Data JPA提供的查询方法已经可以解决大部分的应用场景,但是对于某些业务来说,我们还需要灵活的构造查询条件,这时就可以使用@Query注解,结合JPQL的语句方式完成查询 @Que ...

  9. Spring Data JPA 实现多表关联查询

    本文地址:https://liuyanzhao.com/6978.html 最近抽出时间来做博客,数据库操作使用的是 JPA,相对比 Mybatis 而言,JPA 单表操作非常方便,增删改查都已经写好 ...

随机推荐

  1. 利用forwardInvocation实现消息重定向

    在obj-c中我们可以向一个实例发送消息,相当于c/c++ java中的方法调用,只不过在这儿是说发送消息,实例收到消息后会进行一些处理.比如我们想调用一个方法,便向这个实例发送一个消息,实例收到消息 ...

  2. Java split字符串中包含.的情况

    "a.b".split(".")的语句会返回[],必须进行转义, "a.b".split("\\.")

  3. lufylegend库 LGraphics扭曲图片

    lufylegend库 LGraphics扭曲图片 <!DOCTYPE html> <html lang="en"> <head> <me ...

  4. eclipse安装git插件

    用Eclipse开发,有时需要团队协作,git就是个比较好的选择.下面简单介绍一下git插件的安装方法:   1.Help -- install new software 打开插件安装界面 2.点ad ...

  5. ArcGIS10.2直连PostgreSQL存在问题

    现象: 将下载到的libeay32.dll, libiconv-2.dll, libintl-8.dll, libpq.dll, ssleay32.dll文件拷贝到Desktop 安装目录的bin目录 ...

  6. 2017年试试Web组件化框架Omi

    Open and modern framework for building user interfaces. Omi的Github地址https://github.com/AlloyTeam/omi ...

  7. Quartz_理解2

    一.核心概念   Quartz的原理不是很复杂,只要搞明白几个概念,然后知道如何去启动和关闭一个调度程序即可.   1.Job 表示一个工作,要执行的具体内容.此接口中只有一个方法 void exec ...

  8. 微信小程序 引用其他js里的方法

    微信小程序中,在微信官方开发文档我们可以知道 小程序的目录结构 . 一个小程序页面由四个文件组成,一个小程序页面的四个文件具有相同路径与文件名,由此我们可知一个小程序页面对应着一个跟页面同名的js文件 ...

  9. Kafka 0.10 Producer网络流程简述

    1.Producer 网络请求 1.1 Producer Client角度 KafkaProducer主要靠Sender来发送数据给Broker. Sender: 该线程handles the sen ...

  10. ZeroMQ初探

    概述 ZeroMQ(也称为 ØMQ,0MQ 或 zmq)是一个可嵌入的网络通讯库(对 Socket 进行了封装). 它提供了携带跨越多种传输协议(如:进程内,进程间,TCP 和多播)的原子消息的 so ...