4

我的 Grails 应用程序使用 Spring Security 并具有通常UserUserRole、 和Role类。这些类的建模方式很少见,因为在或中都没有hasMany映射。相反,这些类仅通过.UserRoleUserRole

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.JOIN和之间的区别并不完全清楚FetchMode.SELECT,所以如果有人可以让我明白这一点,我将不胜感激。

4

1 回答 1

6

我尝试了几种组合但得到了相同的结果 - 如果您查看生成的 SQL,原始查询中没有连接,因此它必须执行额外的查询来加载用户和角色。

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

def usersByRole = UserRole.executeQuery(
   'select ur from UserRole ur ' +
   'left join fetch ur.user ' +
   'left join fetch ur.role')
于 2013-05-13T20:41:27.333 回答