Grails最佳方法迭代域类的所有ID

13

我有这样的代码:

Book.list().each {
  // real code actually does something more useful
  println "My id is " + it.id
}
我认为,为了访问id,加载整个Book对象有点浪费。在Grails中,有一个load()方法,只需操作ID即可。我想知道这里是否有相应的方法来加载所有域实例?我应该使用HQL吗?还是应该保持原样?
PS:这让我想是否应该为大多数GORM方法(查找器等)提供一个选项,使其仅“加载”而不是“获取”目标类。
4个回答

9

当你想要避免使用HQL时,结合投影的标准查询可以解决你的问题。

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

Hibernate SQL 日志显示只有 ID 从数据库中加载,而不是整个 Books:select this_.id as y0_ from book this_
可以将 Criteria 查询作为 Book 领域类的命名查询添加,以便轻松访问 ID 列表。

8

您可以使用HQL只返回所需的字段

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


我认为,为了可读性考虑,使用namedQueries或标准查询比SQL更好,特别是当您的查询变得更加复杂时。 - David Sawyer

5
+1 对@Ruben的答案表示赞同,但您可以简化它,只需将其缩短为

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

并获得相同的结果!


-2

除非Book对象包含大量数据,否则我会选择使用Book.list来保持简单。

请记住,load()实际上并不会访问数据库,它只是构造一个带有id设置的对象。


我刚试了一下load方法,似乎只有在访问id以外的属性时才会访问数据库。 - aldrin
是的,这就是使用.load而不仅仅是new Book(id:2)的原因,它创建了一个代理对象,在访问时延迟加载对象。 - Michael Legart
我认为如果Book类没有太多的数据(少于100k),使用Book.list()可能是可以的。 - Jarred Olson
@aldrin load 不适用于需要超过 id 的情况。 - Fletch

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接