309

CriteriaまたはHQLを使用することの長所と短所は何ですか? Criteria API は、Hibernate でクエリを表現するための優れたオブジェクト指向の方法ですが、Criteria クエリは HQL よりも理解/構築が難しい場合があります。

Criteria と HQL はいつ使用しますか? どのユースケースで何を優先しますか? それとも単に好みの問題ですか?

4

22 に答える 22

219

私は主に動的クエリの基準クエリを好みます。たとえば、いくつかのパラメータに応じて、いくつかの順序を動的に追加したり、いくつかの部分 (制限など) を除外したりする方がはるかに簡単です。

一方、静的で複雑なクエリには HQL を使用しています。これは、HQL の方が理解しやすく読みやすいためです。また、HQL はもう少し強力だと思います。たとえば、さまざまな結合タイプに対してです。

于 2008-10-13T12:54:37.357 に答える
93

HQL と criteriaQuery の間にはパフォーマンスの点で違いがあります。criteriaQuery を使用してクエリを起動するたびに、テーブル名の新しいエイリアスが作成されますが、これはどの DB に対しても最後にクエリされたキャッシュには反映されません。これにより、生成された SQL をコンパイルするオーバーヘッドが発生し、実行に時間がかかります。

フェッチ戦略について[http://www.hibernate.org/315.html]

  • Criteria は、マッピングの遅延設定を尊重し、ロードしたいものがロードされることを保証します。これは、1 つの Criteria クエリによって、複数の SQL 即時 SELECT ステートメントが発生し、遅延マップされていないすべての関連付けとコレクションを含むサブグラフをフェッチする可能性があることを意味します。「方法」や「内容」さえも変更したい場合は、setFetchMode() を使用して、特定のコレクションまたは関連付けの外部結合フェッチを有効または無効にします。基準クエリは、フェッチ戦略 (結合、選択、副選択) も完全に尊重します。
  • HQL は、マッピングの遅延設定を尊重し、ロードしたいものがロードされることを保証します。これは、1 つの HQL クエリが、すべての非遅延マッピングされた関連付けとコレクションを含むサブグラフを取得するために、複数の SQL 即時 SELECT ステートメントになる可能性があることを意味します。「どのように」、さらには「何を」変更したい場合は、LEFT JOIN FETCH を使用して、特定のコレクションまたは null 許容の多対 1 または 1 対 1 の関連付けの外部結合フェッチを有効にするか、JOIN FETCH を使用して有効にします。 null 非許容の多対 1 または 1 対 1 の関連付けの内部結合フェッチ。HQL クエリは、マッピング ドキュメントで定義された fetch="join" を尊重しません。
于 2008-12-04T17:30:58.353 に答える
42

Criteriaはオブジェクト指向APIですが、HQLは文字列の連結を意味します。つまり、オブジェクト指向のすべての利点が適用されます。

  1. 他のすべてが等しい場合、OOバージョンはエラーが発生しにくくなります。古い文字列はHQLクエリに追加される可能性がありますが、有効なCriteriaオブジェクトのみがCriteriaツリーに追加できます。事実上、Criteriaクラスはより制約されています。
  2. オートコンプリートを使用すると、OOがより検出しやすくなります(したがって、少なくとも私にとっては使いやすくなります)。クエリのどの部分がどこに行くのかを必ずしも覚えておく必要はありません。IDEはあなたを助けることができます
  3. また、構文の詳細(どの記号がどこに行くかなど)を覚えておく必要はありません。知っておく必要があるのは、メソッドを呼び出してオブジェクトを作成する方法だけです。

HQLはSQL(ほとんどの開発者はすでによく知っています)に非常によく似ているため、これらの「覚えておく必要はありません」という引数はそれほど重要ではありません。HQLがもっと異なっていれば、これはもっと重要です。

于 2008-10-13T14:42:18.013 に答える
37

私は通常、どの入力がどのデータに使用されるかわからない場合に Criteria を使用します。ユーザーが 1 から 50 の項目のいずれかを入力できる検索フォームのように、ユーザーが何を検索するのかわかりません。ユーザーが何を検索しているかを確認しながら、基準にさらに追加するのは非常に簡単です。その状況でHQLクエリを入れるのはもう少し面倒だと思います。HQLは、自分が何を望んでいるかを正確に知っている場合に最適です.

于 2008-10-13T22:07:33.123 に答える
33

HQL ははるかに読みやすく、Eclipse Hibernate プラグインなどのツールを使用してデバッグしやすく、ログに記録しやすくなっています。基準クエリは、多くの動作が実行時に決定される動的クエリを作成する場合に適しています。SQL を知らなくても、Criteria クエリを使用することは理解できますが、全体として、必要なものが事前にわかっている場合は HQL を好みます。

于 2008-10-13T15:28:07.767 に答える
24

基準は、第 2 レベルのクエリ キャッシュで特別な最適化を利用する自然キー ルックアップを指定する唯一の方法です。HQL には、必要なヒントを指定する方法がありません。

ここで詳細情報を見つけることができます:

于 2009-07-10T07:21:51.140 に答える
23

Criteria Api は、Hibernate の優れたコンセプトの 1 つです。私の見解によると、これらはHQLCriteria Apiを区別できる数少ないポイントです。

  1. HQLはデータに対して選択操作と非選択操作の両方を実行することですが、基準はデータを選択するためのものであり、基準を使用して非選択操作を実行することはできません.
  2. HQL は静的クエリの実行に適していますが、Criteria は動的クエリの実行に適しています。
  3. HQL はページネーションの概念をサポートしていませんが、Criteria を使用してページネーションを実現できます。
  4. Criteria は、HQL よりも実行に時間がかかっていました。
  5. Criteria を使用すると、クエリが動的に生成されるためSQL インジェクションに対して安全ですが、HQL ではクエリが固定またはパラメータ化されているため、SQL インジェクションから安全ではありません。
于 2013-05-08T07:48:57.777 に答える
21

基準 API

Criteria API は、動的に生成されるクエリに適しています。そのため、WHERE 句のフィルターや JOIN 句を追加したり、ORDER BY 句や射影列を変更したりする場合、Criteria API を使用すると、SQL インジェクション攻撃を防ぐ方法でクエリを動的に生成できます。

一方、Criteria クエリは表現力が低く、非常に複雑で非効率的な SQL クエリになる可能性さえあります。

JPQLとHQL

JPQL は JPA 標準のエンティティクエリ言語であり、HQL は JPQL を拡張し、Hibernate 固有の機能をいくつか追加します。

JPQL と HQL は非常に表現力が高く、SQL に似ています。Criteria API とは異なり、JPQL および HQL を使用すると、JPA プロバイダーによって生成される基になる SQL クエリを簡単に予測できます。また、基準クエリよりも HQL クエリを確認する方がはるかに簡単です。

エンティティを変更する必要がある場合は、JPQL または Criteria API を使用してエンティティを選択することが理にかなっていることに注意してください。それ以外の場合は、DTO プロジェクションの方がはるかに適しています。

結論

エンティティ クエリ構造を変更する必要がない場合は、JPQL または HQL を使用します。フィルタリングまたはソート基準を変更する必要がある場合、または射影を変更する必要がある場合は、Criteria API を使用してください。

ただし、JPA または Hibernate を使用しているからといって、ネイティブ SQL を使用してはならないというわけではありません。SQL クエリは非常に便利であり、JPQL と Criteria API は SQL の代わりにはなりません。

于 2014-11-09T07:22:50.563 に答える
15

HQL の表現力と簡潔さ、および Criteria の動的な性質の両方の長所を活かすには、 Querydslの使用を検討してください。

Querydsl は、JPA/Hibernate、JDO、SQL、およびコレクションをサポートしています。

私は Querydsl のメンテナーなので、この回答は偏っています。

于 2010-01-11T21:01:56.540 に答える
14

私にとって、基準は理解しやすく、動的クエリを作成するのは非常に簡単です。しかし、私がこれまでに言った欠陥は、選択、プロキシ、デフォルトの 3 種類の FetchModes しかないため、すべての多対一などの関係をロードし、これらすべてのケースで多対一をロードすることです (そうであれば私は間違っているかもしれません)私から:))

Criteria の 2 番目の問題は、完全なオブジェクトをロードすることです。つまり、従業員の EmpName をロードしたい場合は、完全な Employee オブジェクトを作成して、EmpName を取得できます。報告する。ここで、HQL は必要なものをロードするだけで (アソシエーション/リレーションをロードしませんでした)、パフォーマンスを何度も向上させます。

Criteria の特徴の 1 つは、クエリが固定またはパラメーター化されている HQL のように動的なクエリを生成するため、SQL インジェクションから安全ではないため、SQL インジェクションから安全であるということです。

また、aspx.cs ファイルに HQL を記述すると、DAL と密接に結合されます。

全体的な私の結論は、レポートのような HQL なしでは生きていけない場所があるので、それらを使用することです。

于 2009-07-06T12:09:05.183 に答える
12

私にとって Criteria の最大のメリットは、サンプル API です。ここでは、オブジェクトを渡すことができ、hibernate はそれらのオブジェクト プロパティに基づいてクエリを作成します。

それに加えて、クライテリア API には癖があります (休止状態のチームが API を作り直していると思います)。

  • criteria.createAlias("obj") は、可能な外部結合の代わりに内部結合を強制します
  • 同じエイリアスを 2 回作成することはできません
  • 一部の sql 句には、対応する単純な基準がありません (副選択など)。

SQL に似たクエリが必要な場合は HQL を使用する傾向があり (status='blocked' のユーザーから削除)、文字列の追加を使用したくない場合は基準を使用する傾向があります。

HQL のもう 1 つの利点は、すべてのクエリを事前に定義し、それらをファイルなどに外部化することさえできることです。

于 2008-10-14T12:56:33.423 に答える
9

Criteria API は、SQL も HQL も提供しない 1 つの明確な機能を提供します。すなわち。これにより、クエリのコンパイル時のチェックが可能になります。

于 2012-01-23T17:12:14.237 に答える
9

最初はアプリケーションで主に Criteria を使用していましたが、パフォーマンスの問題により HQL に置き換えられました。
主に、いくつかの結合を含む非常に複雑なクエリを使用しているため、Criteria では複数のクエリが発生しますが、HQL では非常に最適化されています。
完全なオブジェクトではなく、特定のオブジェクトに対していくつかのプロパティのみを使用する場合があります。基準では、問題は文字列の連結でもありました。
HQL でユーザーの名前と姓を表示する必要がある場合、それは非常に簡単(name || ' ' || surname)ですが、Crteria ではこれは不可能です。
これを克服するために、ResultTransormers を使用しました。ここでは、必要な結果のためにそのような連結が実装されているメソッドがありました。
現在、主に次のような 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();

この場合、返されるレコードは必要なプロパティのマップです。

于 2012-01-09T22:43:00.107 に答える
7
  • HQLはデータに対して選択操作と非選択操作の両方を実行することですが、基準はデータを選択するためのものであり、基準を使用して非選択操作を実行することはできません
  • HQL は静的クエリの実行に適していますが、Criteria は動的クエリの実行に適しています。
  • HQL はページネーションの概念をサポートしていませんが、Criteria でページネーションを実現できます
  • HQL よりも実行に時間がかかっていた基準
  • Criteria を使用すると、クエリが動的に生成されるため SQL インジェクションに対して安全ですが、HQL ではクエリが固定またはパラメータ化されているため、SQL インジェクションから安全ではありません。

ソース

于 2015-12-05T01:14:13.663 に答える
6

動的の基準クエリは、入力に基づいてクエリを構築できます。Hql クエリの場合、一度構築するとクエリの構造を変更することはできません。

于 2013-01-25T06:54:06.053 に答える
5

ここで死んだ馬を蹴りたくはありませんが、Criteria クエリは現在非推奨であることに言及することは重要です。HQL を使用します。

于 2016-09-14T08:48:21.913 に答える
0

ここでのほとんどの回答は誤解を招くものでありCriteria QueriesHQL実際にはそうではありません。

深く掘り下げていくつかのテストを実行すると、基準クエリが通常の HQL よりもはるかに優れたパフォーマンスを発揮することがわかります。

また、Criteria Queryを使用すると、 HQLにはないオブジェクト指向コントロールを取得できます。

詳細については、こちらの回答をお読みください

于 2016-07-18T23:51:50.150 に答える
0

別の方法があります。hibernate の元の構文に基づいて HQL パーサーを作成することになったので、最初に HQL を解析してから、動的パラメーターを動的に挿入したり、HQL クエリにいくつかの一般的なフィルターを自動的に追加したりできます。それはうまくいきます!

于 2018-01-12T19:00:38.133 に答える