Criteria API和NamedQuery之间的决策是否有启发式/最佳实践/规则集?
到目前为止我的想法:
命名查询通常更具可读性。条件查询更加灵活。
两者都是预编译的。我倾向于尽可能长时间地使用命名查询,然后更改为条件。
但也许通过使用标准 API 来“灵活”查询的冲动是对次优设计(即关注点分离)的暗示?
谢谢
Criteria API和NamedQuery之间的决策是否有启发式/最佳实践/规则集?
到目前为止我的想法:
命名查询通常更具可读性。条件查询更加灵活。
两者都是预编译的。我倾向于尽可能长时间地使用命名查询,然后更改为条件。
但也许通过使用标准 API 来“灵活”查询的冲动是对次优设计(即关注点分离)的暗示?
谢谢
命名查询更加优化(它们被解析/准备一次)。条件查询是动态的(它们不是预编译的,尽管一些 JPA 提供程序,例如 EclipseLink 维护一个条件准备缓存)。
我只会将标准用于动态查询。
例如,当必须根据变量和多个搜索条件动态生成查询时,条件查询是一个不错的选择。
对于静态查询,JPQL 更具可读性,我更喜欢使用它们而不是条件查询。你可能会失去一些安全感,但单元测试应该让你更有信心。
另一种观点是,虽然条件查询不那么可读,但它是类型安全的,因此为您提供编译时类型检查。如果您在有许多实体和许多查询的项目中更改数据库,那么在编译时查看哪些查询因更改而出错是非常有帮助的。
另一方面,我不确定这是否比 JPQL 的简单性更有益
实际上,我浏览了 Hibernate (4.3.0-SNAPSHOT) 源代码和 EclipseLink (2.5.0-SNAPSHOT) 源代码,并查看了每一个中的 JPA 实现。
EclipseLink 显然不是您描述的方式的线程安全。具体来说,它会尝试重复重新计算连接。
Hibernate 的实现对我来说看起来是线程安全的。我不是 100% 确定,但似乎确实如此。我想说的是,由于未指定,因此不保证将来会这样做。
但是,我会警告你,我认为你不会获得太多。从我所看到的来看,查询的大部分编译实际上是在“createQuery”阶段完成的,因此您甚至不会获得太多缓存结果。
JPA 还提供了一种使用@NamedQuery 和@NamedQueries 注释构建静态查询(如命名查询)的方法。在 JPA 中,尽可能选择命名查询而不是动态查询被认为是一种很好的做法。来自http://www.objectdb.com/java/jpa/query/api