質問

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

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

役に立ちましたか?

解決

ほとんどの場合、動的クエリには基準クエリを使用します。たとえば、パラメータに応じて、いくつかの順序を動的に追加したり、一部の部分(制限など)を残したりする方がはるかに簡単です。

一方で、HQLの理解と読み取りがはるかに簡単なため、静的で複雑なクエリにHQLを使用しています。また、HQLはもう少し強力です。さまざまな結合タイプ用。

他のヒント

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

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

  
      
  • 基準は、マッピングの遅延設定を尊重し、ロードするものがロードされることを保証します。これは、1つのCriteriaクエリが、すべての非遅延マップアソシエーションとコレクションを含むサブグラフをフェッチするためのいくつかのSQL即時SELECTステートメントをもたらす可能性があることを意味します。 「方法」を変更する場合は、さらに、「what」もsetFetchMode()を使用して、特定のコレクションまたは関連付けの外部結合フェッチを有効または無効にします。基準クエリは、フェッチ戦略も完全に尊重します(結合vs選択vs副選択)。
  •   
  • HQLは、マッピングの遅延設定を尊重し、ロードするものが確実にロードされるようにします。これは、1つのHQLクエリが、すべての非遅延マップアソシエーションおよびコレクションを含むサブグラフをフェッチするためのいくつかのSQL即時SELECTステートメントをもたらす可能性があることを意味します。 「方法」を変更する場合は、そして、「何」でも、LEFT JOIN FETCHを使用して、特定のコレクションまたはNULL入力可能な多対1または1対1の関連付けの外部結合フェッチを有効にします。または、JOIN FETCHを使用して、非NULL多対1または1対1の関連付け。 HQLクエリはfetch =" join"を尊重しません。マッピング文書で定義されています。
  •   

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

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

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

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

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

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

ここでさらに情報を見つけることができます:

基準ApiはHibernateの優れたコンセプトの1つです。私の見解によると、これらは HQL Criteria Api

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

私にとっては、動的クエリの理解と作成は簡単です。しかし、これまでに言った欠陥は、Select、Proxy、Defaultの3種類のFetchModeしかないため、すべての多対1などの関係をロードすることです。これらすべての場合、多対1をロードします(そうであれば、間違っているかもしれません私を:))

Criteriaの2番目の問題は、完全なオブジェクトをロードすることです。つまり、従業員のEmpNameだけをロードしたい場合、これを思い付かない場合は、完全なEmployeeオブジェクトを作成します。 >報告が本当にうまくいかない。 HQLがロードする(関連付け/関係をロードしなかった)ので、何回でもパフォーマンスを向上させることができます。

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

また、ur aspx.csファイルにHQLを記述した場合、ur DALと密結合します。

全体的な結論として、レポートのようにHQLなしでは生活できない場所があるので、それらを使用します。そうしないと、基準の管理がより簡単になります。

両方の長所を活用するには、HQLの表現力と簡潔さ、および基準の動的な性質により、 Querydsl

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

私はQuerydslのメンテナーなので、この答えには偏りがあります。

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

それに加えて、基準APIには次のような癖があります(休止状態チームはAPIを作り直していると思います)。

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

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

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

Criteria APIは、クエリフィルターが実行時に動的に適用される場合、動的に生成されたクエリにより適しています。したがって、 SQLを防止するにはインジェクション攻撃は、動的クエリを作成する際に、Criteria APIが非常に良い選択です。

基準クエリは表現力が低く、非常に複雑で非効率的な SQLで生成されたクエリ。私はかつてCriteria APIがデフォルトのクエリメソッドである大規模なエンタープライズアプリケーションに参加しましたが、広範なコードレビューでさえ、最終的にどのSQLクエリになるかわからないという恐怖を克服できませんでした。

JPQLまたはHQLははるかに表現力があり、関連する生成されたSQLクエリを予測するのがはるかに簡単です。また、基準のクエリよりもHQLクエリのレビューがはるかに簡単です。

ほとんどのエンティティクエリのユースケースでは、動的なwhere句が必要ないため、動的なクエリの基準を残したまま、ほとんどのクエリをJPQLで実装できます。

JPQLまたはCriteria APIでエンティティを選択するのは、それらを変更する必要がある場合に意味があることに注意してください。それ以外の場合、DTO投影のパフォーマンスが向上します。 こちらの記事で詳細をご覧ください

>

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

最初はアプリケーションで主にCriteriaを使用していましたが、パフォーマンスの問題によりHQLに置き換えられました。
主に、複数の結合を持つ非常に複雑なクエリを使用しているため、Criteriaでは複数のクエリになりますが、HQLでは非常に最適化されています。
ケースは、完全なオブジェクトではなく、特定のオブジェクトに対していくつかのプロパティのみを使用することです。 Criteriaでは、問題は文字列の連結でもありました。
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();

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

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

ソース

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

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

また、動的クエリには基準クエリを使用します。しかし、削除クエリにはhqlを好みます。たとえば、親ID「xyz」の子テーブルからすべてのレコードを削除する場合、HQLによって簡単に実現できますが、条件APIの場合、最初にn個の削除クエリを起動する必要があります(nは子の数)テーブルレコード。

ここでの回答のほとんどは誤解を招くものであり、 Criteria Queries HQL よりも遅いことに言及していますが、実際にはそうではありません。

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

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

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

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

この投稿はかなり古いものです。ほとんどの回答は、JPA基準ではなくHibernate基準について述べています。 JPA 2.1では、CriteriaDelete / CriteriaUpdate、およびフェッチする内容を正確に制御するEntityGraphが追加されました。 Javaはオブジェクト指向であるため、基準APIの方が優れています。それがJPAが作成される理由です。 JPQLがコンパイルされると、SQLに変換される前にASTツリー(OOモデル)に変換されます。

HQLは、SQLインジェクションのようなセキュリティの懸念を引き起こす可能性があります。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top