JPA命名查询 vs Criteria API?

29

是否有一种启发式/最佳实践/规则集来决定使用Criteria API还是NamedQuery

我的想法如下:
命名查询通常更易读。Criteria查询更加灵活。
两者都是预编译的。我倾向于尽可能地使用命名查询,然后再改为Criteria查询。

但也许通过使用Criteria API来“弯曲”查询的渴望是指向次优的设计(即关注点分离)的暗示?

谢谢

5个回答

37

命名查询更加优化(只需解析/预编译一次)。Criteria查询是动态的(它们没有预编译),尽管一些JPA提供商(如EclipseLink)维护着criteria准备缓存。

我只会在需要动态查询时使用criteria。


5
我喜欢只使用Criteria。将Criteria API与实体的元模型相结合,您可以完全放弃使用String并生成强类型代码,对于Java极客来说,这是真正的乐趣!然而,我发现这个测试实际上表明Criteria的性能甚至比JPQL更差! - Martin Andersson
1
从技术上讲,该性能测试并未使用生成的元模型,而这正是 JPA Criteria API 的最佳部分。一开始我在从 Hibernate Criteria 切换到 JPA 时遇到了很大的困难,但现在我真的更喜欢 JPA。 - Yinzara
@Yinzara 我来晚了,但是你说的JPA Criteria API指的是什么?JPA不是一个规范吗?而Hibernate只是其中之一的实现/提供者?当你说你更喜欢JPA Criteria而不是Hibernate时,你具体指的是哪个提供者? - Willa
这是一个相当古老的帖子 :) 但是该帖子并不是在比较"Hibernate"和"JPA"。它是在比较使用Hibernate Criteria API与Hibernate Named Queries。通常,当您想构建动态查询时,Criteria查询非常好。命名查询更适合具有仅参数更改而不是结构的查询,因为它只被解析一次,不必每次使用时重新构建。使用JPA标准元模型可能是最好的方法,但这需要生成的代码。 - Yinzara

10

当需要基于变量和多个搜索条件动态生成查询时,标准查询是一个不错的选择。

对于静态查询,JPQL更易读,我更喜欢使用它们而非标准查询。您可能会失去一些安全性,但单元测试应该让您更加自信。


4
另一种观点认为,虽然标准查询语言不太易读,但它是类型安全的,因此可以在编译时进行类型检查。如果在存在许多实体和查询的项目中更改数据库,则在编译时查看由于更改而出现的错误查询非常有帮助。
另一方面,我不确定这比JPQL的简单性更有益。

3
我实际上查看了Hibernate(4.3.0-SNAPSHOT)源代码和EclipseLink(2.5.0-SNAPSHOT)源代码,并查看了每个JPA实现。 EclipseLink在你描述的方式中显然不是线程安全的。 具体来说,它会尝试反复重新计算联接。Hibernate的实现在我看来是线程安全的。虽然我不能100%确定,但它似乎是这样的。我会说由于未指定,这并不能保证将来仍然成立。然而,我会警告你,我认为你不会获得太多收益。从我所看到的情况来看,查询的大部分编译实际上是在“createQuery”阶段完成的,因此您甚至不会获得太多缓存结果的好处。

2
JPA还提供了一种构建静态查询的方式,即使用@NamedQuery和@NamedQueries注解创建命名查询。在可能的情况下,JPA认为优先使用命名查询而不是动态查询是一种好的实践。来自http://www.objectdb.com/java/jpa/query/api

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接