JPA 命名查询与条件 API?
在 Criteria API 和 NamedQuery 之间做出决定是否存在启发式/最佳实践/规则集?
到目前为止我的想法:
命名查询通常更具可读性。条件查询更加灵活。
两者都是预编译的。我倾向于尽可能长时间地依赖使用命名查询,然后更改为条件。
但也许 通过使用标准 API 来“灵活化”查询的冲动是否暗示了次优设计(即关注点分离)?
谢谢
Is there a heuristic/best practice/ruleset for a decision between the Criteria API and NamedQuery?
My thoughts so far :
Named queries are generally more readable. Criteria queries are more flexible.
Both are precompiled. I tend to rely on using named queries as long as possible, then changing to criteria.
But maybe
the urge to "flexify" the query by using the criteria API is a hint to suboptimal design (i.e. separation of concerns)?
Thank you
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
命名查询更加优化(它们被解析/准备一次)。标准查询是动态的(尽管某些 JPA 提供程序(例如 EclipseLink)维护标准准备缓存,但它们不是预编译的)。
我只会对动态查询使用条件。
Named queries are more optimal (they are parsed/prepared once). Criteria queries are dynamic, (they are not precompiled, although some JPA providers such as EclipseLink maintain a criteria prepare cache).
I would use criteria only for dynamic queries.
例如,当必须基于变量和多个搜索条件动态生成查询时,条件查询是一个不错的选择。
对于静态查询,JPQL 更具可读性,与标准查询相比,我更喜欢使用它们。您可能会失去一些安全性,但单元测试应该会让您更加自信。
Criteria queries are a good choice when a query must be generated dynamically, based of variable and multiple search criteria, for example.
For static queries, JPQL is much more readable, and I prefer using them than criteria queries. You could lose some safety, but the unit tests should make you more confident.
另一个观点是,虽然标准查询的可读性不太好,但它是类型安全的,因此为您提供编译时类型检查。如果您在有许多实体和许多查询的项目中更改数据库,那么在编译时查看哪些查询因更改而出错确实很有帮助。
另一方面,我不确定这比 JPQL 的简单性更有利
Another viewpoint is that although criteria query is not so readable, it is typesafe, therefore provides you compile time type checking. If you change the database in projects where there are many entities and many queries, it is really helpful to see at compile time what queries went wrong because of the change.
On the other hand, I'm not sure that is more beneficial than the simpleness of JPQL
我实际上浏览了 Hibernate (4.3.0-SNAPSHOT) 源代码和 EclipseLink (2.5.0-SNAPSHOT) 源代码,并查看了每个源代码中的 JPA 实现。
EclipseLink 显然不是您所描述的线程安全的。具体来说,它尝试重复重新计算连接。
Hibernate 的实现对我来说看起来是线程安全的。我不是百分百确定,但似乎确实如此。我想说的是,这不能保证将来是真的,因为它没有被指定。
不过,我要警告你,我认为你不会有太多收获。从我的观察来看,查询的大部分编译实际上是在“createQuery”阶段完成的,因此您甚至不会获得太多缓存结果。
I actually went through the Hibernate (4.3.0-SNAPSHOT) source and the EclipseLink (2.5.0-SNAPSHOT) source and looked through the JPA implementation in each.
EclipseLink is clearly not thread safe in the manner you describe. Specifically it tries to recalculate joins repeatedly.
Hibernate's implementation looks thread safe to me. I'm not 100% sure, but it does seem to be. I would say that this is not guaranteed to be true in the future since it isn't specified.
However, I will warn you, I don't think you're going to gain much. From what I'm looking at, much of the compilation of the query is actually done during the "createQuery" phase so you wouldn't even gain much caching the results.
JPA 还提供了一种使用 @NamedQuery 和 @NamedQueries 注释构建静态查询(如命名查询)的方法。在可能的情况下,优先使用命名查询而不是动态查询被认为是 JPA 中的一个良好实践。来自 http://www.objectdb.com/java/jpa/query/api
JPA also provides a way for building static queries, as named queries, using the @NamedQuery and @NamedQueries annotations. It is considered to be a good practice in JPA to prefer named queries over dynamic queries when possible. From http://www.objectdb.com/java/jpa/query/api