【问题标题】:Is there any way in Grails to eager fetch the whole record?Grails 中有什么方法可以急切地获取整个记录吗?
【发布时间】:2011-12-27 11:56:59
【问题描述】:

我正在尝试查找 Grails 中是否有任何方法可以急切获取完整记录而不是左连接。

我有两个具有一对多映射的类。当我尝试获取所有记录并呈现为 XML 时,只有“多”端的 ID 进入 XML 文件。有没有办法获取全部记录?

我使用的例子如下:

我有 3 个课程:

用户、书籍和章节

Users 和 Book 具有多对多映射,而 Book 到 Chapters 是一对多映射。我有一个类 UserBook,它定义了多对多关系。现在我有以下代码

user = User.findByUserId(params.userid.toString())
        def books = user.getAllBooks()
        render books as XML

Set<Book>getAllBooks() {
        UserBook.findAllByUser(this).collect {it.book} as Set
    }

上面呈现了一个包含书籍以及每本书的章节 ID 的 XML。我想要的是上面的“书籍”也包含所有章节信息。

谢谢!!

【问题讨论】:

  • 能否提供您的课程示例,以便我们更好地回答您的问题?
  • Michael,我已经按照您的建议提供了示例。谢谢!!

标签: grails grails-orm


【解决方案1】:

文档说:

Grails 使用的默认获取策略是“lazy”,这意味着 该集合将被延迟初始化。这可能导致 n+1 一不小心就会出问题。如果您需要“渴望”获取,您可以 使用 ORM DSL 或将 Eager fetching 指定为查询的一部分

您可以在域类中指定获取策略,但恕我直言,获得 1-m 关系的最佳策略是使用 fetch 或通过添加到域类或 Criteria 的方法加入查询,例如:

// You have a Book with many Authors, then you specify the fetching strategy with eager
def results = Book.list(fetch:[authors:"eager"])

在其他情况下,您可以将条件与 Hibernate Fetch Mode 一起使用:

import org.hibernate.FetchMode as FM
…
def results = c.list {
    maxResults(10)
    firstResult(50)
    fetchMode("aRelationship", FM.JOIN)
}

或者如果你知道HQL更好,那么你可以使用它,因为可以在HQL中表示提取,例如:def result = DomainClass.findAll("HQL_Sentence")

酷啊!!!!

【讨论】:

    【解决方案2】:

    如果您正在寻找包含完整章节信息而非仅 ID 的 XML 输出,请尝试使用“深度”XML 编组(也适用于 JSON):

    XML.use('deep') {
        render books as XML
    }
    

    【讨论】:

      【解决方案3】:

      查看docs section 5.3.4。它是在你的域类中使用 fetchMode 完成的:

      static fetchMode = [things:"eager"]
      

      然而,如果您只是寻找对象的 ID 来填充 XML 文件(或其他字段),我会查看 projection criteria 以获得更好的性能大型集合。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-12-27
        • 1970-01-01
        • 2013-03-26
        • 1970-01-01
        • 1970-01-01
        • 2019-12-23
        相关资源
        最近更新 更多