2011-09-07 64 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