我的Grails应用使用Spring Security,并且具有通常的User
,UserRole
和Role
类。这些类的建模方式并不常见,因为hasMany
或User
中没有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.JOIN
和FetchMode.SELECT
之间的区别,所以如果有人能够直截了当地表达我的意见,我们将不胜感激。
答案 0 :(得分:6)
我尝试了几种组合但结果相同 - 如果你看一下生成的SQL,原始查询中没有连接,所以它必须做额外的查询才能加载用户和角色。
其他人对此域类存在问题 - 看起来GORM中存在一个错误,其中包含由域类组成的复合键,或者类似的东西。通常人们对HQL解决方法感到满意,如果运气好的话,你会这样做:)
def usersByRole = UserRole.executeQuery(
'select ur from UserRole ur ' +
'left join fetch ur.user ' +
'left join fetch ur.role')