JPA命名查询与标准API?

Posted

技术标签:

【中文标题】JPA命名查询与标准API?【英文标题】:JPA Named Queries vs Criteria API? 【发布时间】:2011-11-12 03:22:14 【问题描述】:

Criteria APINamedQuery 之间是否存在启发式/最佳实践/规则集?

到目前为止我的想法: 命名查询通常更具可读性。条件查询更加灵活。 两者都是预编译的。我倾向于尽可能长时间地使用命名查询,然后更改为标准。 但也许 使用标准 API 来“灵活”查询的冲动暗示了次优设计(即关注点分离)?

谢谢

【问题讨论】:

【参考方案1】:

命名查询更加优化(它们被解析/准备一次)。条件查询是动态的(它们不是预编译的,尽管一些 JPA 提供程序(例如 EclipseLink)维护一个条件准备缓存)。

我只会将条件用于动态查询。

【讨论】:

我喜欢只使用标准。将 Criteria API 与实体的元模型相结合,您可以完全放弃使用 String 并生成强类型代码,对于真正有趣的 Java 极客来说!但是,我发现 this 测试实际上表明 Criteria 的性能甚至比 JPQL 还要差! 从技术上讲,性能测试没有使用生成的元模型,这是关于 JPA Criteria API 的最佳部分。刚开始从 Hibernate Criteria 切换到 JPA 时我遇到了很大的困难,但现在我真的更喜欢 JPA 了。 @Yinzara 我迟到了,但是当你说 JPA Criteria API 时,你是什么意思? JPA 不是规范和休眠实现/提供者之一吗?当您说您更喜欢 JPA 标准而不是 Hibernate 时,您会谈论哪个特定的提供商? 这是一个相当古老的线程 :) 但该线程并未将“Hibernate”与“JPA”进行比较。它使用 Hibernate Criteria API 与 Hibernate Named Queries 进行比较。通常,当您要构建动态查询时,条件查询非常好。命名查询更适合仅具有更改的参数但没有更改结构的查询,因为它只解析一次并且每次使用时都不必重新构建。使用 JPA 标准元模型可能是最好的方法,但这需要生成代码。【参考方案2】:

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

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

【讨论】:

【参考方案3】:

另一个观点是,虽然条件查询不那么可读,但它是类型安全的,因此为您提供编译时类型检查。如果您在有许多实体和许多查询的项目中更改数据库,那么在编译时查看哪些查询因更改而出错是非常有帮助的。

另一方面,我不确定这是否比 JPQL 的简单性更有益

【讨论】:

【参考方案4】:

我实际上浏览了 Hibernate (4.3.0-SNAPSHOT) 源代码和 EclipseLink (2.5.0-SNAPSHOT) 源代码,并查看了各自的 JPA 实现。

EclipseLink 显然不是您描述的方式的线程安全。具体来说,它会反复尝试重新计算联接。

Hibernate 的实现在我看来是线程安全的。我不是 100% 确定,但似乎确实如此。我想说的是,由于没有具体说明,因此不保证将来是正确的。

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

【讨论】:

【参考方案5】:

JPA 还提供了一种使用@NamedQuery 和@NamedQueries 注释构建静态查询(作为命名查询)的方法。在 JPA 中,尽可能选择命名查询而不是动态查询被认为是一种很好的做法。来自http://www.objectdb.com/java/jpa/query/api

【讨论】:

以上是关于JPA命名查询与标准API?的主要内容,如果未能解决你的问题,请参考以下文章

JPA 标准 API。使用带参数的 sql 函数调用进行查询

如何为以下语句编写标准构建器 API JPA 查询

Atitit oodbms的查询,面向对象的sql查询jpa jpql hql

JPA 命名查询与 group by 参数名和值

JPA:命名查询数据库独立性

JPA Criteria builder IN 子句查询