我不确定这种关系是否是正确的术语,所以请纠正我。我需要定义一个域类,它映射到数据库中的表。该类需要定义相同类型的关系层次结构。例如,假设我需要使用相同的类对下面的角色进行建模 管理员>经理>主管>联合......等。
class RoleType {
String roleName
String description
static hasMany = [parentType: RoleType]
}
所以,通过父类型,我可以定义层次结构。请注意,它不是继承。我也可以定义与直接孩子的1:m关系。现在,我可以轻松找到包含的对象。例如,如果我需要找到经理(例如,主管,员工)或主管(员工)等下面的所有角色,我会使用Grails。
感谢。
答案 0 :(得分:1)
您所定义的是单向一对多,父母是关系的“所有者”。如果你这样定义:
class RoleType {
String roleName
String description
static hasMany = [children: RoleType]
}
然后你可以这样做:
def superManager = new RoleType(roleName: 'SuperManager')
def manager = new RoleType(roleName: 'Manager')
superManager.addToChildren(manager);
或者我相信你可以像这样简写:
def superManager = new RoleType(roleName: 'SuperManager').addToChildren(roleName: 'Manager').save()
通过定义与[children: RoleType]
的关系,Grails会在名为children
的域上创建一个集合,您可以像访问其他任何属性一样访问该集合,例如myRole.children.each { it.doSomething() }
。
为了更容易使用,您还可以通过添加以下属性使关系成为双向:
RoleType parent
如果使用动态addTo*
方法,则应确保关系的两端都正确设置其属性。请查看this以获取更多参考资料。
这里有几个选项,但我认为GORM没有一种方法可以自动完成。
一种选择是编写自己的递归或迭代方法来抓取并收集所有孩子。可以找到一个例子here。
或者,如果您经常执行此方法并且它成为瓶颈,您可以对数据库进行一些手动操作。您可能具有对RoleType表中的插入和更新进行操作的触发器,这些触发器维护所有RoleType之间的隐式关系列表。
例如,如果您创建RoleType A
- > RoleType B
- > RoleType C
关系,触发器可能会创建(在单独的表格中)RoleType A
- > RoleType B
,RoleType A
- > RoleType C
和RoleType B
- > RoleType C
关系。{{1}}然后,您可以通过单个父查询此表并获取其所有隐含的子项/后代。我已经看到这样做了复杂的ACL处理。