gpt4 book ai didi

grails - 无法避免在 Grails 中选择多对多关系的 n+1

转载 作者:行者123 更新时间:2023-12-01 14:46:35 25 4
gpt4 key购买 nike

我正在使用 Grails 创建一个玩具问答网站,以便学习该平台。我有两个域,帖子和标签,它们之间存在多对多关系。我想打印带有标签的帖子列表。

我不能使用惰性抓取,因为我会遇到 N+1 选择问题

我也不能使用 eager fetching,因为它使用左连接,我无法正确地分页结果。

因此我决定使用以下代码手动获取标签:


static def getList(params) {

ArrayList questions = Question.list(params)

def questionMap = [:]
questions.each {
questionMap.put(it.id, it)
}

if(questions.size()>0) {
Tag.executeQuery('SELECT q.id, t FROM Tag t JOIN t.questions q \
WHERE q.id in ( :list ) ', [ list:questions.collect{ it.id } ] ).each { questionMap.get(it[0]).tags.add(it[1]) }
}

return questions
}

然而,当我在 View 中打印标签时:

<g:each in="${questions}" var="question">
${question.title}
<g:each in="${question.tags}" var="tag">
${tag?.text}
</g:each>
</g:each>

无论如何,每个问题都会执行一个查询!这里推荐的方法是什么?

最佳答案

您的代码存在的问题是您没有对Tag 查询的结果做任何事情。此外,为多对多关系创建连接类是一种更好的方法。例如,如果您看到 Spring Security Core 插件,则您有 UserRole 和一个名为 UserRole 的连接类。 Here是示例类。

所以我给你的建议是:

class Tag {
...
}

class Question{
...
}

class QuestionTag implements Serializable {
Tag tag
Question question
static mapping = {
id composite: ['tag','question']
...
}
//need to override equals and hashCode
}

要存储标签的结果,您可以为您的类添加一个 transient 字段:

类问题{ def标签 静态瞬变 = ['标签'] //移除 hasMany。

您现在可以执行您的HQL,在您的问题列表中查找问题实例并设置tags 属性。由于您使用的是一个不返回单个类的 HQL,因此结果未映射为 Tag 对象,因此访问略有不同。

HQL queries can return domain class instances, or Arrays of specified data when the query selects individual fields or calculated values

关于grails - 无法避免在 Grails 中选择多对多关系的 n+1,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15456600/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com