これはHibernate API
の問題ではないようです 、実際にはこれが望ましい動作です。
Query.iterate() :
クエリ結果をIterator
として返します 。クエリに複数の結果が前行に含まれている場合、結果はObject[]
のインスタンスで返されます 。Entities
結果がオンデマンドで初期化されるときに返されます。最初のSQLクエリはidentifiers
を返します のみ。
1+N SQL
を実行します クエリ。最初のクエリはすべてのレコードの識別子のみを返し、返されたイテレータが繰り返されると、WHERE id=N
のようなWHERE句を含む個別のSQLクエリが実行されるたびに 。レコードがキャッシュに存在する場合、最初のクエリが実行され、残りのN個のクエリは実行されず、レコードはキャッシュから取得されます。
Iterator<Employee> iterator1 = session.createQuery("from Employee").iterate(); // SELECT EMP_ID FROM EMP
while(iterator1.hasNext()) {
System.out.println(iterator1.next()); // SELECT * FROM EMP WHERE EMP_ID=?
}
Iterator<Employee> iterator2 = session.createQuery("from Employee").iterate(); // SELECT EMP_ID FROM EMP
while (iterator2.hasNext()) {
System.out.println(iterator2.next()); // From cache, no SQL
}
Query.getResultList() :Executes 1 SQL query
データ全体をロードします。レコードがキャッシュに存在する場合でも、データベースからレコードをロードするために新しいSQLクエリが実行されます。
List<Employee> list1 = session.createQuery("from Employee").list(); // SELECT *FROM EMP
for (Employee e : list1) {
System.out.println(e);
}
List<Employee> list2 = session.createQuery("from Employee").list(); // SELECT *FROM EMP
for (Employee e : list2) {
System.out.println(e);
}