java jpa hibernate_java - JPA和Hibernate - Criteria与JPQL或HQL
java - JPA和Hibernate - Criteria與JPQL或HQL
使用Criteria或HQL有哪些優(yōu)缺點? Criteria API是一種很好的面向?qū)ο蟮姆绞絹肀磉_Hibernate中的查詢,但有時Criteria Queries比HQL更難理解/構(gòu)建。
什么時候使用Criteria和何時使用HQL? 您更喜歡哪種用例? 或者只是品味問題?
21個解決方案
202 votes
我更喜歡Criteria Queries來進行動態(tài)查詢。 例如,根據(jù)某些參數(shù),動態(tài)添加一些排序或保留一些部分(例如限制)要容易得多。
另一方面,我使用HQL進行靜態(tài)和復雜查詢,因為它更容易理解/讀取HQL。 另外,我認為HQL更強大,例如 對于不同的連接類型。
cretzel answered 2019-02-03T19:28:24Z
88 votes
HQL和criteriaQuery之間的性能存在差異,每次使用criteriaQuery觸發(fā)查詢時,它都會為表名創(chuàng)建一個新別名,該別名不反映在任何數(shù)據(jù)庫的最后查詢緩存中。 這導致編譯生成的SQL的開銷,花費更多的時間來執(zhí)行。
關(guān)于獲取策略[[http://www.hibernate.org/315.html]]
Criteria尊重映射中的惰性設(shè)置,并保證加載您想要加載的內(nèi)容。 這意味著一個Criteria查詢可能會導致多個SQL立即SELECT語句獲取具有所有非延遲映射關(guān)聯(lián)和集合的子圖。 如果要更改“how”甚至“what”,請使用setFetchMode()為特定集合或關(guān)聯(lián)啟用或禁用外部聯(lián)接提取。 Criteria查詢也完全尊重提取策略(join vs select vs subselect)。
HQL尊重映射中的延遲設(shè)置,并保證加載要加載的內(nèi)容。 這意味著一個HQL查詢可能會導致多個SQL立即SELECT語句獲取具有所有非延遲映射關(guān)聯(lián)和集合的子圖。 如果要更改“how”甚至“what”,請使用LEFT JOIN FETCH為特定集合啟用外部聯(lián)接提取,或者為可以多對一或一對一關(guān)聯(lián)的可空連接,或使用JOIN FETCH啟用 內(nèi)部聯(lián)接獲取非可空的多對一或一對一關(guān)聯(lián)。 HQL查詢不遵循映射文檔中定義的任何fetch =“join”。
Varun Mehta answered 2019-02-03T19:29:08Z
38 votes
Criteria是面向?qū)ο蟮腁PI,而HQL意味著字符串連接。 這意味著面向?qū)ο蟮乃泻锰幎歼m用:
在其他條件相同的情況下,OO版本不太容易出錯。 任何舊字符串都可以附加到HQL查詢中,而只有有效的Criteria對象才能將其添加到Criteria樹中。 實際上,Criteria類更受限制。
通過自動完成,OO更容易被發(fā)現(xiàn)(因此至少對我來說更容易使用)。 您不一定需要記住查詢的哪些部分在哪里; IDE可以幫助你
您也不需要記住語法的細節(jié)(比如哪些符號去哪里)。 您需要知道的是如何調(diào)用方法和創(chuàng)建對象。
由于HQL非常像SQL(大多數(shù)開發(fā)人員已經(jīng)非常熟悉),因此這些“不必記住”的參數(shù)不會帶來太大的影響。 如果HQL更加不同,那么這將更加重要。
Craig Walker answered 2019-02-03T19:29:57Z
34 votes
當我不知道哪些輸入將用于哪些數(shù)據(jù)時,我通常使用Criteria。 就像在搜索表單上,用戶可以輸入1到50個項目中的任何一個,我不知道他們將要搜索什么。 當我檢查用戶正在搜索的內(nèi)容時,很容易在標準上添加更多內(nèi)容。 我認為在這種情況下放置HQL查詢會有點麻煩。 當我確切地知道我想要什么時,HQL很棒。
Arthur Thomas answered 2019-02-03T19:30:20Z
31 votes
HQL更容易閱讀,使用Eclipse Hibernate插件等工具更容易調(diào)試,更容易記錄。 Criteria查詢更適合構(gòu)建動態(tài)查詢,其中許多行為是在運行時確定的。 如果您不了解SQL,我可以理解使用Criteria查詢,但總體而言,如果我知道我想要的是什么,我更喜歡HQL。
Brian Deterling answered 2019-02-03T19:30:42Z
22 votes
條件是指定利用二級查詢緩存中的特殊優(yōu)化的自然鍵查找的唯一方法。 HQL沒有任何方法來指定必要的提示。
你可以在這里找到更多信息:
[http://tech.puredanger.com/2009/07/10/hibernate-query-cache/]
Alex Miller answered 2019-02-03T19:31:17Z
20 votes
Criteria Api是Hibernate的一個很好的概念。 根據(jù)我的觀點,這些是我們可以在HQL和Criteria Api之間做出改動的幾點
HQL是對數(shù)據(jù)執(zhí)行選擇和非選擇操作,但Criteria僅用于選擇數(shù)據(jù),我們不能使用條件執(zhí)行非選擇操作。
HQL適用于執(zhí)行靜態(tài)查詢,其中Criteria適合執(zhí)行動態(tài)查詢
HQL不支持分頁概念,但我們可以使用Criteria實現(xiàn)分頁。
標準用于執(zhí)行比HQL更多的時間。
使用Criteria我們可以安全地使用SQL注入因為它的動態(tài)查詢生成,但是在HQL中,因為您的查詢是固定的或參數(shù)化的,所以SQL注入沒有安全性
Arvind answered 2019-02-03T19:32:12Z
13 votes
對我而言,Criteria非常容易理解和制作動態(tài)查詢。 但我到目前為止所說的缺陷是它加載了所有多個等關(guān)系,因為我們只有三種類型的FetchModes,即Select,Proxy和Default,在所有這些情況下它加載了多個(如果有幫助,可能是我錯了) 我:))
Criteria的第二個問題是它加載了完整的對象,即如果我只想加載一個員工的EmpName,它就不會想出它提出完整的Employee對象,我可以從中獲取EmpName,因為它真的很糟糕報告。 HQL只是加載(沒有加載關(guān)聯(lián)/關(guān)系)你想要的,所以多次提高性能。
Criteria的一個特性是它可以安全地使用SQL注入,因為它的動態(tài)查詢生成在HQL中,因為ur查詢是固定的或參數(shù)化的,所以從SQL注入是不安全的。
另外,如果你在ur aspx.cs文件中編寫HQL,那么你就與你的DAL緊密結(jié)合了。
總的來說,我的結(jié)論是,有些地方,如果沒有像報告這樣的HQL,你就無法生存。所以使用其他標準更容易管理。
Zafar answered 2019-02-03T19:33:00Z
12 votes
為了充分利用這兩方面的優(yōu)勢,HQL的表現(xiàn)力和簡潔性以及Criteria的動態(tài)性質(zhì)考慮使用Querydsl。
Querydsl支持JPA / Hibernate,JDO,SQL和Collections。
我是Querydsl的維護者,所以這個答案是有偏見的。
Timo Westk?mper answered 2019-02-03T19:33:35Z
11 votes
對我來說,Criteria上最大的勝利是Example API,你可以在其中傳遞一個對象,而hibernate將根據(jù)這些對象屬性構(gòu)建一個查詢。
除此之外,標準API有其怪癖(我相信hibernate團隊正在重新編寫api),如:
criteria.createAlias(“obj”)強制內(nèi)部聯(lián)接而不是可能的外部聯(lián)接
你不能兩次創(chuàng)建相同的別名
一些sql子句沒有簡單的標準對應(yīng)物(如子選擇)
等等
當我想要類似于sql的查詢時,我傾向于使用HQL(從status ='blocked'的用戶中刪除),當我不想使用字符串追加時,我傾向于使用條件。
HQL的另一個優(yōu)點是您可以事先定義所有查詢,甚至可以將它們外部化到文件中。
Miguel Ping answered 2019-02-03T19:34:37Z
9 votes
Criteria api提供了SQL或HQL都不提供的一個獨特功能。即。 它允許編譯時檢查查詢。
user1165443 answered 2019-02-03T19:35:00Z
9 votes
在運行時動態(tài)應(yīng)用查詢過濾器時,Criteria API更適合動態(tài)生成的查詢。 因此,為了在構(gòu)建動態(tài)查詢時防止SQL注入攻擊,Criteria API是一個非常好的選擇。
Criteria查詢的表達性較差,您可以輕松地使用非常復雜且低效的SQL生成查詢。 我曾經(jīng)加入了一個大型企業(yè)應(yīng)用程序,其中Criteria API是默認的查詢方法,甚至沒有廣泛的代碼審查可以克服不知道我們最終會得到什么SQL查詢的恐怖。
JPQL或HQL更具表現(xiàn)力,預(yù)測相關(guān)生成的SQL查詢要容易得多。 查看一個HQL查詢比使用標準查詢要容易得多。
大多數(shù)實體查詢用例不需要動態(tài)where子句,因此您可以使用JPQL實現(xiàn)大多數(shù)查詢,同時保留動態(tài)的Criteria。
值得注意的是,如果您需要修改它們,選擇具有JPQL或Criteria API的實體是有意義的。 否則,DTO投影表現(xiàn)更好。 查看此文章了解更多信息。
Vlad Mihalcea answered 2019-02-03T19:35:48Z
7 votes
在我們的應(yīng)用程序中,我們主要使用Criteria,但由于性能問題而將其替換為HQL。
主要是我們使用具有多個連接的非常復雜的查詢,這導致在Criteria中進行多次查詢,但在HQL中進行了非常優(yōu)化。
情況是我們只在特定對象上使用幾個屬性而不是完整對象。 使用Criteria,問題也是字符串連接。
假設(shè)您需要在HQL中顯示用戶的姓名和姓氏,這很容易(name || ' ' || surname),但在Crteria中這是不可能的。
為了解決這個問題,我們使用了ResultTransormers,其中有一些方法可以為所需的結(jié)果實現(xiàn)這種連接。
今天我們主要使用這樣的HQL:
String hql = "select " +
"c.uuid as uuid," +
"c.name as name," +
"c.objective as objective," +
"c.startDate as startDate," +
"c.endDate as endDate," +
"c.description as description," +
"s.status as status," +
"t.type as type " +
"from " + Campaign.class.getName() + " c " +
"left join c.type t " +
"left join c.status s";
Query query = hibernateTemplate.getSessionFactory().getCurrentSession().getSession(EntityMode.MAP).createQuery(hql);
query.setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
return query.list();
所以在我們的例子中,返回的記錄是所需屬性的映射。
Bojan Kraut answered 2019-02-03T19:36:49Z
7 votes
HQL是對數(shù)據(jù)執(zhí)行選擇和非選擇操作,但Criteria僅用于選擇數(shù)據(jù),我們不能使用條件執(zhí)行非選擇操作
HQL適用于執(zhí)行靜態(tài)查詢,其中Criteria適合執(zhí)行動態(tài)查詢
HQL不支持分頁概念,但我們可以使用Criteria實現(xiàn)分頁
標準過去需要花費更多時間來執(zhí)行HQL
使用Criteria,我們可以安全地使用SQL注入因為它的動態(tài)查詢生成,但是在HQL中,因為您的查詢是固定的或參數(shù)化的,所以SQL注入沒有安全性。
資源
Premraj answered 2019-02-03T19:37:39Z
5 votes
Criteria查詢動態(tài)我們可以根據(jù)我們的輸入構(gòu)造查詢。如果Hql查詢是靜態(tài)查詢,一旦我們構(gòu)造我們就無法改變查詢的結(jié)構(gòu)。
user1679378 answered 2019-02-03T19:38:01Z
4 votes
我不想在這里踢死馬,但重要的是要提到Criteria查詢現(xiàn)已棄用。 使用HQL。
Eskir answered 2019-02-03T19:38:23Z
1 votes
我也更喜歡Criteria Queries進行動態(tài)查詢。 但我更喜歡使用hql進行刪除查詢,例如,如果從子表中刪除父ID為'xyz'的所有記錄,則可以通過HQL輕松實現(xiàn),但對于標準API,我們必須首先觸發(fā)n個刪除查詢,其中n是子數(shù) 表記錄。
Punit Patel answered 2019-02-03T19:38:45Z
0 votes
這里的大多數(shù)答案都是誤導性的,并提到Criteria Queries比HQL慢,實際情況并非如此。
如果深入研究并執(zhí)行一些測試,您會發(fā)現(xiàn)Criteria Queries的性能比常規(guī)HQL好得多。
而且使用Criteria Query,您可以獲得面向?qū)ο蟮目丶?#xff0c;這與HQL不同。
有關(guān)更多信息,請閱讀此答案。
Pritam Banerjee answered 2019-02-03T19:39:26Z
0 votes
還有另一種方式。 我最終創(chuàng)建了一個基于hibernate原始語法的HQL解析器,因此它首先解析HQL然后它可以動態(tài)注入動態(tài)參數(shù)或自動為HQL查詢添加一些常見的過濾器。 它很棒!
Wallace Peng answered 2019-02-03T19:39:48Z
0 votes
這篇文章很老了。 大多數(shù)答案都是關(guān)于Hibernate標準,而不是JPA標準。 JPA 2.1添加了CriteriaDelete / CriteriaUpdate,以及控制究竟要獲取內(nèi)容的EntityGraph。 Criteria API更好,因為Java是OO。 這就是創(chuàng)建JPA的原因。 編譯JPQL時,在轉(zhuǎn)換為SQL之前,它將被轉(zhuǎn)換為AST樹(OO模型)。
Sunnyday answered 2019-02-03T19:40:11Z
-3 votes
HQL可能導致SQL注入等安全問題。
Emad Aghayi answered 2019-02-03T19:40:33Z
總結(jié)
以上是生活随笔為你收集整理的java jpa hibernate_java - JPA和Hibernate - Criteria与JPQL或HQL的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: win10接u盘没反应怎么办啊 电脑插U
- 下一篇: 怎么将系统安装到u盘里 安装系统到U盘的