简体   繁体   English

域类中的包含关系(Grails)

[英]Containment relationship in domain class (Grails)

I'm not sure whether it is the right terminology for this kind of relationship, so please correct me. 我不确定这是否是用于这种关系的正确术语,所以请纠正我。 I need to define a domain class, which maps to a table in the database. 我需要定义一个域类,该域类映射到数据库中的表。 The class needs to define a hierarchy of relationships of the same type. 该类需要定义相同类型关系的层次结构。 For eg, say I need to model the below roles with the same class Admin > Manager > Supervisor > associate .. etc. 例如,说我需要使用相同的类Admin> Manager> Supervisor> associate .. etc对以下角色进行建模。

class RoleType {
    String roleName
    String description

    static hasMany = [parentType: RoleType]
}

so, through the parenttype, I may be able to define the hierarchy. 因此,通过父类型,我也许可以定义层次结构。 Note that it is not inheritance. 请注意,它不是继承。 I may also define 1:m relationship towards the immediate child aswell. 我也可以定义与直系孩子的1:m关系。 Now, how easily I can find the contained objects. 现在,我可以轻松找到所包含的对象。 For eg, if I need to find all the roles below Manager (say, Supervisor, Associate), or under supervisor (associate) etc. I use Grails. 例如,如果我需要在Manager(例如,Supervisor,Associate)之下或在supervisor(Associate)之下找到所有角色,则可以使用Grails。

thanks. 谢谢。

Defining the relationship 定义关系

What you're defining is a unidirectional one-to-many, with the parent being the 'owner' of the relationship. 您要定义的是单向一对多,父级是关系的“所有者”。 If you define it like this: 如果您这样定义:

class RoleType {
    String roleName
    String description
    static hasMany = [children: RoleType]
}

Then you can do something like this: 然后,您可以执行以下操作:

def superManager = new RoleType(roleName: 'SuperManager')
def manager = new RoleType(roleName: 'Manager')

superManager.addToChildren(manager);

Or I believe you can shorthand the same thing like this: 或者,我相信您可以简写如下相同内容:

def superManager = new RoleType(roleName: 'SuperManager').addToChildren(roleName: 'Manager').save()

By defining the relationship with [children: RoleType] , Grails creates a collection on the domain called children that you can access like any other property, eg myRole.children.each { it.doSomething() } . 通过定义与[children: RoleType]的关系,Grails在名为children的域上创建一个集合,您可以像其他任何属性一样访问该集合,例如myRole.children.each { it.doSomething() }

To make it easier to work with, you could also make the relationship bidirectional by adding the following property: 为了更轻松地使用它,您还可以通过添加以下属性来使关系双向化:

RoleType parent

If you use the dynamic addTo* methods, they should ensure that both ends of the relationship get their properties correctly set. 如果使用动态addTo*方法,则它们应确保正确设置关系的两端。 Have a look at this for additional reference. 看看这个作为其他参考。

Retrieving all descendants 检索所有后代

You have a few options here, but I don't think there's a way built into GORM to do it automatically. 您在这里有一些选择,但是我认为GORM内置没有一种自动执行此操作的方法。

One option would be to write your own recursive or iterative method that grabs and collects all of the children. 一种选择是编写您自己的递归或迭代方法,以捕获并收集所有子代。 An example of this can be found here . 一个例子可以在这里找到。

Alternatively, if you execute this method a lot and it become a bottleneck, you could do some manual manipulation of your database. 另外,如果您大量执行此方法,并且成为瓶颈,则可以对数据库进行一些手动操作。 You might have triggers that operate on inserts and updates in your RoleType table that maintain lists of implicit relationships between all RoleTypes. 您可能具有对RoleType表中的插入和更新进行操作的触发器,这些触发器维护所有RoleType之间的隐式关系列表。

For example, if you create a RoleType A -> RoleType B -> RoleType C relationship, the triggers might create (in a separate table) a RoleType A -> RoleType B , RoleType A -> RoleType C , and RoleType B -> RoleType C relationship. 例如,如果创建RoleType A > RoleType B > RoleType C关系,则触发器可能会(在单独的表中)创建RoleType A > RoleType BRoleType A > RoleType CRoleType B > RoleType C关系。 You could then query this table by a single parent and get all of its implied children/descendants. 然后,您可以由单亲查询此表,并获取其所有隐含的子代/后代。 I've seen this done for complex ACL processing. 我已经看到完成复杂的ACL处理。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM