2011-09-07 103 views
26

Criteria APINamedQuery之间是否存在启发式/最佳实践/规则集?JPA命名查询vs Criteria API?

我的想法到目前为止:
命名查询通常更具可读性。标准查询更灵活。
两者都是预编译的。我倾向于尽可能使用命名查询,然后更改为条件。

但也许 通过使用标准API“查询”查询的要求暗示了次优设计(即关注点分离)?

谢谢

回答

33

命名查询更优化(它们被解析/准备一次)。 Criteria查询是动态的(它们不是预编译的,虽然一些JPA提供者(例如EclipseLink维护准备准备缓存))。

我只会使用标准进行动态查询。

+0

我同意。好答案! – Robin

+4

我喜欢只使用Criteria。将Criteria API与实体的元模型相结合,您可以完全放弃使用String并生成强类型代码,这对于真正有趣的Java怪胎来说非常有趣!但是,我发现[this](http://milestonenext.blogspot.se/2013/02/jpql-vs-criteria.html)测试显示Criteria的性能比JPQL差得多! –

+0

从技术上讲,性能测试不使用生成的关于JPA Criteria API最好的部分的Metamodel。在从Hibernate Criteria转换到JPA的过程中,我遇到了很大的困难,但现在我真的更喜欢JPA。 – Yinzara

10

条件查询是一个不错的选择时,必须动态地生成一个查询,基于的变量和多个搜索条件,例如。

对于静态查询,JPQL更具可读性,我更喜欢使用它们而不是条件查询。你可能会失去一些安全性,但单元测试应该让你更有信心。

3

另一个观点是,尽管标准查询不太明了,但它是类型安全的,因此可以为您提供编译时类型检查。如果在有很多实体和许多查询的项目中更改数据库,那么在编译时查看由于更改而导致哪些查询出错是非常有用的。

在另一方面,我不知道那是比JPQL

2

的简单我居然通过Hibernate(4.3.0-SNAPSHOT)源和的EclipseLink去更有益(2.5.0-快照)源代码,并查看每个JPA实现。

以您描述的方式,EclipseLink显然不是线程安全的。具体来说,它试图重新计算连接。

Hibernate的实现看起来对我来说是线程安全的。我不是100%确定,但似乎确实如此。我想说,由于没有具体说明,所以未来这不能保证是真实的。

但是,我会警告你,我不认为你会获得很多。从我所看到的,查询的大部分编译实际上是在“createQuery”阶段完成的,所以你甚至不会获得很多缓存结果。

1

JPA还提供了使用@NamedQuery和@NamedQueries注释将静态查询构建为命名查询的方法。在可能的情况下,在JPA中认为优先考虑动态查询上的命名查询是一种很好的做法。从http://www.objectdb.com/java/jpa/query/api