Query.list()
使用和到底有什么区别Query.iterator()
?
使用这两种方法是否有任何性能增强。我的意思是他们中的任何一个都实现了延迟加载?
或者Query.iterator()最终是否与query.list().iterate()
还有为什么不只有Criteria.iterator()
Criteria.list()
Query.list()
使用和到底有什么区别Query.iterator()
?
使用这两种方法是否有任何性能增强。我的意思是他们中的任何一个都实现了延迟加载?
或者Query.iterator()最终是否与query.list().iterate()
还有为什么不只有Criteria.iterator()
Criteria.list()
Query.list():执行 1 个 SQL 查询并加载整个数据。即使记录存在于缓存中,也会执行新的 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);
}
Query.iterate():执行 1+N 个 SQL 查询。第一个查询只返回所有记录的标识符,当返回的迭代器被迭代时,每次执行一个单独的 SQL 查询,其中包含一个 WHERE 子句,如“WHERE id=N”。如果记录存在于缓存中,则执行第一个查询,不执行其余 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
}
如果实例已经在会话中(一级缓存)或二级缓存iterate()
将提供更好的性能。
如果它们尚未缓存,iterate()
则将比简单查询要慢list()
并且可能需要许多数据库命中。
javadoc 说:
将查询结果作为迭代器返回。如果查询包含多个结果前行,则结果将在 Object[] 的实例中返回。
作为结果返回的实体按需初始化。第一个 SQL 查询仅返回标识符。
(强调我的)
+----------------------------------------------+-----------------------------------------------+
| list() | iterate() |
+----------------------------------------------+-----------------------------------------------+
| Return type is List | Return type is Iterate |
| All records loads at single database request | For each record, one database hit is made |
| This is faster if cache is not available | This is very slower if cache is not available |
| Eager loading | Lazy loading |
+----------------------------------------------+-----------------------------------------------+
对于列表():
Query query = session.createQuery("from Employee");
List list = query.list(); // SELECT * FROM EMP
Iterator iterator = list.iterator();
while(iterator.hasNext()){
}
对于迭代():
Query query = session.createQuery("from Employee");
Iterator iterator = query.iterate(); // SELECT * FROM EMP
while(iterator.hasNext()){
// SELECT * FROM EMP WHERE EMP_ID=?
}