2010-03-16 28 views
36

我见过人们使用多对一的映射来表示一对一的关系。我也在Gavin King的一本书和文章中阅读了这篇文章。Hibernate - 为什么要使用多对一来表示一对一?

例如,如果客户可以有一个确切的送货地址和送货地址只能属于一个客户,映射给定为:

<class name="Customer" table="CUSTOMERS"> 
    ... 
    <many-to-one name="shippingAddress" 
       class="Address" 
       column="SHIPPING_ADDRESS_ID" 
       cascade="save-update" 
       unique="true"/> 
    ... 
</class> 

这本书的原因是(引用它):

“你不关心什么是对关联的目标方面,所以你可以把它像一个到一个协会没有许多的一部分。”

我的问题是,为什么使用many-to-one而不是one-to-oneone-to-one是什么使它成为many-to-one不太理想的选择?

谢谢。

回答

28

有几种方法可以在数据库中实现一对一关联:您可以共享主键,但也可以使用具有唯一约束的外键关系(一个表具有引用的外键列关联表的主键)。

在后面的例子中,映射这个的休眠方式是使用many-to-one关联(允许指定外键)。

原因很简单:你不关心 什么是对 关联的目标侧,这样你就可以像 一个一对一的关联对待它没有很多 部分。 所有你想要表达的是“这个 实体有一个属性是 引用另一个 实体”,并使用外键字段 表示该关系。

换句话说,使用many-to-one是映射一到一个外键关联(这实际上比共享主密钥一个一对一关联也许更频繁)的方式。

+1

可以实现更灵活和同样的事情你能否提供一个例子来阐明你关于映射“外键关系与唯一约束”的观点?由于这种关系在逻辑上是一对一的,为什么在冬眠时将它映射为多对一呢? – KyleM 2013-03-05 22:32:36

+5

这似乎回答_when_,但不_why _...? – 2013-07-26 09:41:11

+0

尽管如此,不能使用'inverse =“true”'。它不适用于“多对一”。 – pavanlimo 2013-12-27 11:53:36

3

我会说这个问题与对象 - 关系阻抗不匹配有着根本的关系。为了能够将两个对象表示关联到一个数据库中,你需要在它们的表之间建立某种关系。但是,数据库只知道1:N关系:所有其他数据都是从它派生的。

对于关系数据库和对象语言,开发人员需要找到他/她想表示的概念(在本例中为1:1关系)的最不自然的表示。

0

据我所知,hibernate要求两个对象的主键以1对1的关系匹配。许多到1避免了这一要求。

然而,许多对1丢失的信息,应该只有一个或可能没有多方面的对象。

3

最大的区别是,用共享密钥一对一映射这两个对象是相互绑定的,它们一起存在。

f.e.如果你创建一个地址类绑定到具有相同名称的表,每个人都会有一个确切的地址...

Person类,属性:地址 表的人,列:ID,命名 表地址,列:ID,城市

随着多对一的关系表结构改变了一点,但可以达到同样的效果......

  • 类人 - >属性:地址
  • 表人 - >列:ID,姓名, addressid(FK)
  • 表地址 - >列:ID, 城市

...但即使更多。现在,这个人可以有多个地址:

  • 类Person - >属性:地址
  • 表人 - >列:ID,姓名, addressid(FK),shippingaddressid(FK)
  • 表地址 - >列:ID, 城市

两个外键(addressid和shippingaddressid)可以指向一个单一的数据库条目......或将一个地址可能属于2-3人。所以从人们的角度来看,这是多对一的,它是地址方面的一对多。

只是猜测一个只有一个项目的一对多关联是什么样子?是的,就像一对一...

注意:地址实际上应该是一个值对象,不应该在数据库中共享(所以这是一个愚蠢的例子,但我想它会没事的)

因此,在短期:

  1. 的OR映射一到一个更难处理
  2. 一对一已经
  3. 使用许多它的局限性,一个反而是莫可以用
相关问题