2012-01-10 87 views
13

我有这样的代码,最好的方法:Grails的迭代域类的所有ID

Book.list().each { 
    // real code actually does something more useful 
    println "My id is " + it.id 
} 

这令我有点浪费,每个整本书的对象被加载刚刚访问ID。在Grails中有一个load()方法,当你只想在ID上操作时,我想知道是否有加载所有域实例的等价物?我应该使用HQL吗?或者我应该保持现状?

PS:这让我不知道是否应该提供给最GORM方法(查找器等),这导致其只是“负荷”,而不是选择“获取”目标类

回答

8

您可以使用HQL只返回领域需要

Book.executeQuery("select b.id from Book b");

+0

为了便于阅读,我会说使用'namedQueries'或条件查询比SQL好得多,尤其是在查询变得更加复杂时。 – 2015-08-27 19:50:41

-2

除非Book对象包含大量的数据,我只是用Book.list去保持简单。

请记住,加载()实际上没有命中数据库,它只是构造一个id集合的对象。

+0

我刚刚尝试加载,它似乎是击中数据库,如果您尝试访问除id以外的任何属性。 – aldrin 2012-01-10 13:04:18

+0

是的,这就是使用.load代替原来的Book(id:2)的原因,它创建了一个代理对象,它在访问时延迟加载对象。 – 2012-01-10 13:41:46

+0

我同意如果Book类没有很多数据(小于100k)使用Book.list()可能没问题。 – 2012-01-10 14:17:55

9

组合条件查询与当你要避免使用HQL投影解决您的问题。

def criteria = Book.createCriteria() 
    def result = criteria.list { 
     projections { 
      property 'id' 
     } 
    } 

Hibernate的SQL日志显示,只有ID被从数据库加载,而不是整个书籍:select this_.id as y0_ from book this_

标准查询还可以添加为Book域类中的named query,从而可以轻松访问标识列表。

5

+1 @鲁本的答案,但你可以缩短它简单地

def criteria = Book.withCriteria { 
    projections { 
     property 'id' 
    } 
} 

,并得到了相同的结果!