Grails N+1查询

4
我的Grails应用程序使用Spring Security,并且具有通常的User,UserRole和Role类。这些类的建模方式有点不寻常,因为在User或Role中没有任何hasMany映射。相反,这些类仅通过UserRole引用。
class UserRole implements Serializable {
  User user
  Role role
}

我的理解是出于性能原因,将关系建模成这样,特别是为了减少N+1查询的可能性。

在我的应用程序的某个部分,我需要加载所有用户及其角色。考虑到上述问题,我尝试以如下方式完成:

def usersByRole = UserRole.createCriteria().list {
  fetchMode("user", FetchMode.JOIN)
  fetchMode("role", FetchMode.JOIN)
}

然而,当我尝试访问User对象

usersByRole.each { it.user }

需要发出一个单独的查询来从User表中检索数据,因此我遇到了正是我试图避免的问题。我还尝试了以下方法,但它也存在同样的问题。

def usersByRole = UserRole.createCriteria().list {
  fetchMode("user", FetchMode.SELECT)
  fetchMode("role", FetchMode.SELECT)
}

我必须承认,我并不完全清楚 FetchMode.JOINFetchMode.SELECT 之间的区别,如果有人能够帮我弄清楚,那将不胜感激。

1个回答

6
我尝试了几种组合,但结果都相同 - 如果您查看生成的SQL,原始查询中没有连接,因此必须进行额外的查询以加载用户和角色。
其他人在这个域类上也遇到了问题 - 看起来GORM存在一个由域类组成的复合键的错误,或者类似于这样的东西。通常人们会用HQL解决问题,并且希望您也能如此幸运 :)
def usersByRole = UserRole.executeQuery(
   'select ur from UserRole ur ' +
   'left join fetch ur.user ' +
   'left join fetch ur.role')

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