首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >grails hasOne与直接成员变量

grails hasOne与直接成员变量
EN

Stack Overflow用户
提问于 2012-10-16 00:46:14
回答 3查看 7.4K关注 0票数 23

假设我有一个grails域类,如下所示

代码语言:javascript
复制
class Person {
    Address address
}

我也可以将它声明为

代码语言:javascript
复制
class Person {
  static hasOne = [address:Address]
}

第二种方法是将外键移动到Address表,而不是person表。

这种方式与另一种方式相比有什么实际的好处(或缺点)?据我所知,它们都会使用外键,这只是一个外键在哪里的问题。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-10-16 01:09:04

如果地址表中存在外键,则该地址只能有一个人。如果外键在person表中,则多个person可以拥有相同的地址。

这不是关于哪种方式更好/更差的问题。这是关于什么是正确的数据建模方法。

票数 30
EN

Stack Overflow用户

发布于 2013-04-23 03:34:06

我发现在Grails中使用hasOne特别令人困惑。例如,此问题询问当按如下方式声明toOne关系时会发生什么:

代码语言:javascript
复制
class Person {
  static hasOne = [address: Address]
}

如上所述,这会导致person_id外键出现在地址表中,这意味着每个地址只能指向一个人。然后,我发现奇怪的是,即使代码写成“一个人有一个地址”,实际结果是“一个地址有一个人”。

事实上,按照上面的定义,(在数据库级别)没有任何东西可以阻止多个地址记录指向同一个人,这意味着一个人实际上不一定要有一个地址。

有趣的是,如果您像这样创建Address类,您将获得相同的数据库表示:

代码语言:javascript
复制
class Address {
    Person person
}

person_id外键将出现在Address表中,就像前面的示例一样,但显然,如果不以某种方式定义这种关系,您就无法在代码中从Person获取地址。

同样有趣的是,如果您在数据库中对Person和Address之间的toMany关系进行建模,您将使用相同的表布局。您可以将父数据库的主键(person_id)放入子表。从数据库的角度来看,使用hasOne创建的结构与toMany关系创建的结构相同。

当然,我们不仅仅是在创建数据库表,我们还在创建一些具有相关行为的Grails域类,以及一些关系语义的实施。在这个特定的业务示例中,您可能不希望与多个人共享相同的地址记录,而只是希望单独存储地址(也许是为一个人有多个地址的那一天做准备)。我可能会投票支持这种方法:

代码语言:javascript
复制
class Person {
    Address address

    static constraints = {
        address unique:true
    }
}

address_id外键将位于Person表中,并且唯一约束将强制没有两个Person记录指向同一地址。

票数 25
EN

Stack Overflow用户

发布于 2014-02-01 04:39:57

我的建议是:

代码语言:javascript
复制
class Person {
  ...
  static hasOne = [address: Address]
}

class Address {
    ...
    static belongsTo = [person: Person]
}

一个人有一个地址,该地址属于一个人。

这样,当您删除一个人时,地址也会被删除,没有问题。

我认为这是更好的方法。

票数 9
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12900221

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档