Spring Data JPA进阶-Specifications和Querydsl
来源:互联网 发布:西安行知中学初中部 编辑:程序博客网 时间:2024/05/16 05:27
本篇介绍一下Spring Data JPA中能为数据访问程序的开发带来更多便利的特性,我们知道,Spring Data repository的配置很简单,一个典型的repository像下面这样:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
第一个方法表示根据email查询一个Customer,第二个方法表示根据lastName和排序条件查询一个Customer的集合,第三个方法表示根据fristName和分页的信息查询一页Customer
这样的方式非常简单,甚至不用编写方法的实现就可以实现查询的功能,但是这仍然有个弊端,如果查询条件增长,方法会越来越多,如果能动态的组装查询条件就好了
那么,可以吗?答案当然是yes
我们都知道JPA提供了Criteria API,下面我们就用一个例子,展示一下Criteria的使用,想象这样一个场景,我们想针对长期客户,在生日那天给他发一段祝福,我们怎么做呢?
使用Criteria API
我们有两个条件,生日和长期客户,我们假设两年前注册的就是长期客户吧,怎么用JPA 2.0的Criteria API实现呢:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
我们先创建了一个LocalDate对象,然后是三行样板代码啊,后面两行是建立查询条件,然后通过where子句连在一起,然后执行查询
上面查询有两个问题
- 第一,由于每次要先建立CriteriaBuilder,CriteriaQuery,Root,所以导致查询条件的重用和扩展性不是很好
- 第二,上面程序可读性一般,并不能一目了然知道程序在干嘛
使用Specifications
为了重用查询条件,我们引入了Specification接口,这是从Eric Evans’ Domain Driven Design 一书中的概念衍生出来的,它为对一个实体查询的谓词定义了一个规范,实体类型由Specification接口的泛型参数来决定,这个接口只包含下面一个方法:
- 1
- 2
- 3
我们现在可以通过一个工具类很容易的使用它:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
诚然,这并不是最优雅的代码,但是至少很好地解决了我们重用判定条件的需求,如何执行呢,很简单,我们只要让repository继承JpaSpecificationExecutor接口即可:
- 1
- 2
- 3
然后可以像下面这样调用:
- 1
- 2
默认实现会为你提供CriteriaQuery,Root,CriteriaBuilder等对象,通过给定的Specification应用判定条件,然后执行查询,这样的好处就是我们可以随意组合查询条件,而不用写很多个方法,Specifications工具类提供了一写遍历方法来组合条件,例如and(…)、or(…)等连接方法,还有where(…)提供了更易读的表达形式,下面我们看一下效果:
- 1
相比JPA Criteria API的原生接口,我们的实现更加具有扩展性和可读性,当时实现Specification的时候需要一点小波折,但这是值得的
使用Querydsl
为了解决上述的痛苦,一个叫Querydsl的开源项目也提供了类似的解决方案,但是实现有所不同,提供了更有好的API,而且不仅支持JPA,还支持Hibernate,JDO,Lucene,JDBC甚至是原始集合的查询
为了使用Querydsl,需要在pom.xml中引入依赖并且配置一个额外的APT插件
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
下面就可以通过QCustomer来实现我们上述的功能了
- 1
- 2
- 3
- 4
上面的写法不仅读来很顺畅,BooleanExpressions还可以直接重用,免去使用更多包装方法的写法,更酷的是还可以得到IDE代码自动完成的支持,要执行查询,跟Specification类似,让repository继承QueryDslPredicateExecutor接口即可:
- 1
- 2
- 3
可以通过下面的方式调用
- 1
- 2
- 3
总结
Spring Data JPA repository抽象允许通过把JPA Criteria API包装到Specification中来简化开发,还可以使用Querydsl,实现方法也很简单,分别集成JpaSpecificationExecutor或者QueryDslPredicateExecutor即可,当然,如果需要的话,一起使用也没问题
- Spring Data JPA进阶-Specifications和Querydsl
- Spring Data JPA进阶——Specifications和Querydsl
- Spring Data JPA进阶——Specifications和Querydsl
- Spring Data JPA进阶——Specifications和Querydsl
- Spring Data JPA的Specifications和Querydsl
- Spring Data JPA教程, 第五部分: Querydsl(未翻译)
- Spring data JPA中使用Specifications动态构建查询
- Spring data JPA中使用Specifications动态构建查询
- Spring Data JPA进阶-Spring-data-jpa全方位介绍
- JPA和spring data
- Spring Data JPA进阶-@Query注解
- Spring Data JPA进阶-调用存储过程
- Spring-data-rest 和Spring-data-jpa
- JPA和Spring-Data-JPA简介
- jpa和spring data jpa的理解
- spring data jpa和hibernate jpa
- JPA和Spring-Data-JPA简介
- JPA和Spring-Data-JPA简介
- spring boot之创建第一个Spring boot项目
- python变量及运算
- Java jsoup多线程爬虫(爬豆瓣图书封面)
- C#学习笔记4-string和StringBuilder
- ios导航栏rightBarButtonItems多个按钮自定义设置
- Spring Data JPA进阶-Specifications和Querydsl
- 非监督特征学习与深度学习(五)----Softmax 回归(Softmax Regression)
- Java的String、StringBuilder以及StringBuilder和StringBuffer的区别
- MySQL——不含公共字段和id的多个表的一对一关联查询
- ArrayList源码分析
- vim编辑文件去除^M及解决办法
- Ubuntu下通过命令查看电脑的内存条使用情况
- 二叉树的递归与非递归遍历(前序、中序、后序)
- CSDN下载积分的获取方式