Hibernate Criteriaのサポートは、データベースから返される結果を制限するためのsetMaxResults()
メソッドを提供します。
私は彼らのドキュメントでこれに対する答えを見つけることができません-これはどのように実装されていますか?結果セット全体をクエリしてから、リクエスト番号のみを返しますか?それとも、データベース側のクエリを本当に制限しているのでしょうか(mySqlのようにLIMITキーワードを考えてください)。
クエリが多くの結果を返す可能性がある場合、setMaxResults()
がデータベース内のすべての行をクエリするかどうかを本当に知る必要があるため、これは重要です(これは悪いことです)。
また、データベース側の行数を本当に制限している場合、このクロスデータベースをどのように実現しますか(すべてのrdbmsがmySqlのようにLIMIT機能をサポートしているとは限らないため)。
Hibernateは、クエリによって返される結果を制限するようにデータベースに要求します。これは、データベース固有のメカニズムを使用してこれを行う方言を介して行われます(したがって、SQL Serverの場合、「select top n * from table」のような処理を実行し、Oracleは「select * from table where rownum <n」を実行します。 "、MySQLは" select * from table limit n "などを実行します)。次に、データベースが返すものを返すだけです。
クラス_org.hibernate.dialect.Dialect
_には、supportsLimit()
というメソッドが含まれています。方言サブクラスがこのメソッドをオーバーライドする場合、データベースフレーバーにネイティブな方法で行制限処理を実装できます。このコードがクラスのどこから呼び出されているかを確認できます org.hibernate.loader.LoaderprepareQueryStatement
という名前のメソッドがあり、Wordを検索するだけですlimit。
ただし、方言がこの機能をサポートしていない場合は、ResultSet
イテレータに対してハードチェックが行われ、Javaオブジェクト(エンティティ)の結果が構築されなくなることを保証します。制限に達しました。このコードもLoader
にあります。
私はHibernateとHibernateSearchの両方を使用していますが、基盤となる実装を見なくても、すべての結果が返されるわけではないことがわかります。すべての結果を返す同じクエリを実装し、それを変更して最初の結果と最大の結果を設定し(ページネーションを実装するため)、パフォーマンスが大幅に向上しました。
彼らはおそらくこれに方言固有のSQLを使用します。 MySQLではLIMIT、OracleではROWNUM。エンティティマネージャーは、使用している方言を認識しているため、これは簡単です。
最後に、このクエリに対してSQL Hibernateが生成しているものを本当に確認したい場合は、エンティティマネージャー/ファクトリを作成するときに「show_sql」プロパティをtrueに設定するだけで、実行中のすべてのSQLがコンソールに出力されます。
HQLは、SQLのようにクエリ内の制限をサポートしていません。また、setMaxResults()
のみをサポートしています。
setMaxResults()
がLIMITクエリに変換されるかどうかを確認するには、SQLログをオンにします。
私は質問が少し古いことを知っています。しかし、はいsetMaxResults()
は、データベース側の行数を本当に制限しています。
Hibernate SQLの出力を実際に調べると、次のSQLステートメントがクエリに追加されていることがわかります。
limit ?