域类中的包含关系(Grails)

时间:2010-06-25 12:27:53

标签: hibernate grails

我不确定这种关系是否是正确的术语,所以请纠正我。我需要定义一个域类,它映射到数据库中的表。该类需要定义相同类型的关系层次结构。例如,假设我需要使用相同的类对下面的角色进行建模 管理员>经理>主管>联合......等。

class RoleType {
    String roleName
    String description

    static hasMany = [parentType: RoleType]
}

所以,通过父类型,我可以定义层次结构。请注意,它不是继承。我也可以定义与直接孩子的1:m关系。现在,我可以轻松找到包含的对象。例如,如果我需要找到经理(例如,主管,员工)或主管(员工)等下面的所有角色,我会使用Grails。

感谢。

1 个答案:

答案 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 BRoleType A - > RoleType CRoleType B - > RoleType C关系。{{1}}然后,您可以通过单个父查询此表并获取其所有隐含的子项/后代。我已经看到这样做了复杂的ACL处理。