org.hibernate.Query .iterate()VS .getResultList()查询生成

时间:2014-08-12 14:34:14

标签: oracle hibernate hql

我正在使用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中的问题或者是什么。

1 个答案:

答案 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);
}
相关问题