Grails / GORM - 使用' hasMany'将关联映射到整个类层次结构

时间:2014-03-11 21:32:06

标签: grails groovy uml gorm class-diagram

我有一个名为Projects的grails应用程序的以下类图:

enter image Class Diagrammhere

现在我想在grails中创建实际的域类。但我有一个问题:我不知道如何在最佳实践中映射关联#34;办法。最好的解释是Project域类的代码实现示例:

package com.pm.projects

class Project {

    static hasMany = [contracts:Contract, customerContracts:CustomerContract, partnerContracts: PartnerContract]

    String property1
    Integer property2
    Date property3
         .
         .
         .
    TypeN propertyN

    static constraints = {
    }
}

我觉得在hasMany映射中包含所有契约子类是不好的做法,因为在UML类图中,子类继承了它们的超类的关联。因此,从逻辑数据模型的角度来看,我觉得它会更精简,只是为了编码:

static hasMany = [contracts:Contract]

虽然这对我自己来说理论上是正确的方法,但事实证明这些数据的操作技术不可用。例如,

pro = Project.get(params.id)
ProPaconList = pro?.partnercontracts
ProCuconList = pro?.customercontracts

创建两个合同列表,一个用于partnercontracts,另一个用于customercontracts。

是否可以在不包含hasMany地图中的子类的情况下实现类似的结果?即使是,更一般的问题是:可以将多个地图与UML类图表的关联进行比较,其方式是“连接”#34;一个班级不仅与另一个独立的班级,而且还与另一个班级'子类

我没有在网上找到关于这个主题的任何信息,这是一种耻辱,因为我对遵循最佳实践和常规约定的准确数据建模非常感兴趣,而不仅仅是试错。

2 个答案:

答案 0 :(得分:1)

你可以像你认为的那样映射:

static hasMany = [contracts:Contract]

然后,如果您只想获得某种类型的合同,您可以在Project域类上创建一个方法来执行此操作:

class Project {
    static hasMany = [contracts:Contract]

    def findPartnerContracts(){
        return contracts.findAll { contract ->
            contract.instanceOf( PartnerContract )
        }
    }
}

def pro = Project.get(params.id)
def proPaconList = pro?.findPartnerContracts()

我不确定这是否是最佳做法,但......这是一种方法。

小心使用hasMany关联。如果您的收藏过程加剧,您可能会遇到性能问题。请按this presentation查看Burt Beckwith

答案 1 :(得分:1)

在这种情况下,我会说最佳实践'非常依赖于您的应用程序的工作方式以及它所处的环境。您可以采用任何一种方法 - 我认为选择取决于几个问题的答案:

  • 会有多少合约?正如Felipe所说,通过搜索单个关联可能会出现性能问题。
  • 您是否经常想将合同分成不同类型?如果是这样,您的方法可能会更好 - 甚至将它们存储在不同的表格中。请注意,如果将子类存储在同一个表中,GORM / Hibernate将添加一个鉴别器列,以便区分这些类型,这会为检索添加一个小的复杂性。
  • 您可能还会考虑进行显式查询以仅直接从数据库中检索,而不是依赖于GORM关联查询。如果您有大量数据,并且想要某种排序或子集,那么最好进行显式查询(在Project中的方法中封装)以获得您想要的数据。

所以这些只是您可能想要考虑的一些事情,以决定您的最佳实践'是

BTW,对您的类图的一个小评论:由于两个Contract子类都引用了一个时间表,您可以将该关联移到Contract,并让它们都继承它。