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

Posted

技术标签:

【中文标题】Grails 迭代域类的所有 id 的最佳方法【英文标题】:Grails best way to iterate all ids of a domain class 【发布时间】:2012-02-06 17:31:07 【问题描述】:

我有这样的代码:

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

加载每本书的整个对象只是为了访问 id,这让我觉得有点浪费。当您只想对 ID 进行操作时,Grails 中有一个 load() 方法,我想知道这里是否有一个等效的方法来加载所有域实例?我应该使用 HQL 吗?还是我应该保持原样?

PS:这让我想知道是否应该为大多数 GORM 方法(查找器等)提供一个选项,使其仅“加载”而不是“获取”目标类

【问题讨论】:

【参考方案1】:

当您想避免使用 HQL 时,结合投影的条件查询可以解决您的问题。

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

Hibernate SQL 日志显示仅从数据库加载 ID,而不是整个 Books:select this_.id as y0_ from book this_

条件查询也可以作为named query 添加到 Book 域类中,提供对 ID 列表的轻松访问。

【讨论】:

【参考方案2】:

您可以使用 hql 只返回您需要的字段

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

【讨论】:

为了可读性,我想说使用namedQueries 或条件查询比 SQL 好得多,尤其是当您的查询变得越来越复杂时。【参考方案3】:

+1 对于@Ruben 的回答,但您可以将其缩短为简单

def criteria = Book.withCriteria 
    projections 
        property 'id'
    

并获得相同的结果!

【讨论】:

【参考方案4】:

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

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

【讨论】:

我刚刚尝试加载,如果您尝试访问除 id 之外的任何属性,它似乎正在访问数据库。 是的,这就是使用 .load 而不仅仅是 new Book(id:2) 的原因,它创建了一个代理对象,在访问时延迟加载对象。 我同意,如果 Book 类没有很多数据(小于 100k),使用 Book.list() 可能没问题。 @aldrin load 不适用于如果您需要的不仅仅是 id。

以上是关于Grails 迭代域类的所有 id 的最佳方法的主要内容,如果未能解决你的问题,请参考以下文章

如何将 Grails 域类映射到 DTO?

Grails:扩展和嵌入域类有啥区别?

grails 和 spring security acl:仅显示域类的一些实例

来自另一个域类的属性的 Grails 自定义验证器

在另一个域类中查看 grails 域类属性

在 Grails 中使用 java 类