我正在使用org.hibernate.Query
Api来查询结果。但我遇到了一个奇怪的问题。
这是我的查询select DISTINCT abc FROM ABC abc where ORDER BY abc.name ASC
。
我已使用Oracle database
对此进行了测试。
假设我的代码如下
public static List executeQuery(EntityManager em, Query query) {
org.hibernate.Query hibernateQuery = query.unwrap(org.hibernate.Query.class);
// this piece of code is used to fetch data from cache based on id
if(EntityCacheable){
Iterator<Entity> it = hibernateQuery.iterate();
return "";
}else{
//This finnaly return the result
return query.getResultList();
}
}
现在问题出在上面的查询中,hibernateQuery.iterate()
生成如下所示的查询
select abc.id FROM ABC abc where ORDER BY abc.name ASC
,无效。由于order by clause
中的内容也应该在select clause
中。
但是query.getResultList()
生成如下内容,
select abc.id, abc.name FROM ABC abc where ORDER BY abc.name ASC
- 所以我在这里很安全
我可以对我的查询进行更改并继续进行,但这是Hibernate API
中的问题或者是什么。
答案 0 :(得分:1)
这似乎不是Hibernate API
的问题,实际上是期望的行为。
<强> Query.iterate()强>:
将查询结果作为Iterator
返回。如果查询在前一行包含多个结果,则结果将在Object[]
的实例中返回。Entities
返回,因为结果是按需初始化的。第一个SQL查询仅返回identifiers
。
执行1+N SQL
次查询。第一个查询只返回所有记录的标识符,并且当迭代返回的迭代器时,每次执行包含WHERE子句(如WHERE id=N
)的单独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);
}