Grails N + 1查询

时间:2013-05-13 20:09:13

标签: hibernate grails gorm

我的Grails应用使用Spring Security,并且具有通常的UserUserRoleRole类。这些类的建模方式并不常见,因为hasManyUser中没有Role映射。相反,这些类仅通过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 objects

usersByRole.each { it.user }

发出单独的查询以从User表中检索数据,因此我遇到了我试图避免的问题。我也尝试了以下方法,但它遇到了同样的问题。

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

我应该承认,我并不完全清楚FetchMode.JOINFetchMode.SELECT之间的区别,所以如果有人能够直截了当地表达我的意见,我们将不胜感激。

1 个答案:

答案 0 :(得分:6)

我尝试了几种组合但结果相同 - 如果你看一下生成的SQL,原始查询中没有连接,所以它必须做额外的查询才能加载用户和角色。

其他人对此域类存在问题 - 看起来GORM中存在一个错误,其中包含由域类组成的复合键,或者类似的东西。通常人们对HQL解决方法感到满意,如果运气好的话,你会这样做:)

def usersByRole = UserRole.executeQuery(
   'select ur from UserRole ur ' +
   'left join fetch ur.user ' +
   'left join fetch ur.role')