我见过人们使用多对一映射来表示一对一的关系。我也在Gavin King和一篇文章的书中读过这篇文章。
例如,如果客户只能拥有一个送货地址,并且送货地址只能属于一个客户,则映射为:
<class name="Customer" table="CUSTOMERS">
...
<many-to-one name="shippingAddress"
class="Address"
column="SHIPPING_ADDRESS_ID"
cascade="save-update"
unique="true"/>
...
</class>
这本书的理由是(引用它):
“您不关心关联的目标端是什么,因此您可以将其视为 to-one 关联,而不需要许多部分。”< / p>
我的问题是,为什么要使用many-to-one
而不是one-to-one
? one-to-one
使many-to-one
成为不太理想的选项的原因是什么?
感谢。
答案 0 :(得分:33)
有几种方法可以在数据库中实现一对一关联:您可以共享主键,但也可以使用具有唯一约束的外键关系(一个表具有引用该键的外键列相关表的主键)。
在后一种情况下,映射它的hibernate方法是使用many-to-one
关联(允许指定外键)。
原因很简单:你不在乎 什么在目标方面 协会,所以你可以像对待它一样 没有多少人的一对一协会 部分。 你想要的只是表达“这个 实体有一个属性 引用另一个的实例 实体“并使用外键字段 代表那种关系。
换句话说,使用many-to-one
是映射一对一外键关联的方式(实际上可能比共享主键更频繁 - 一对一协会)。
答案 1 :(得分:5)
最大的区别是,通过共享密钥一对一映射,两个对象相互绑定,它们一起存在。
f.e。如果你创建一个人和一个地址类绑定到同名的表,每个人将只有一个地址......
多对一关系表结构稍有变化,但可以实现相同的效果......
......但更多。现在这个人可以有多个地址:
两个外键(addressid和shippingaddressid)可以指向单个数据库条目......或者一个地址可以属于2-3个人。所以从一个人的角度来看,这是多对一的,这是地址方面的一对多。
并猜测只有1项的一对多关联是什么样的?是的,就像一对一......
注意:地址实际上应该是值对象,不应该在DB中共享(所以这是一个愚蠢的例子,但我想它将是o.k。)
简而言之:
答案 2 :(得分:3)
我想说这个问题与对象 - 关系阻抗不匹配有根本的关系。为了能够将数据库中的两个对象表示相关联,您需要在它们的表之间建立某种关系。但是,数据库只知道1:N关系:所有其他关系都来自它。
对于关系数据库和对象语言,开发人员可以找到他/她想要表示的概念中最不自然的表示(在这种情况下,是1:1的关系)。
答案 3 :(得分:0)
甚至在官方的Hibernate文档中:http://docs.jboss.org/hibernate/core/3.3/reference/en/html/associations.html#assoc-bidirectional-121。
这并非完全不合理。 多对一结尾说:我通过我的一个列映射到-one end的ID。您将使用完全相同的数据库模式进行多对一。
答案 4 :(得分:0)
据我了解,hibernate要求两个对象的主键在1对1的关系中匹配。多对1可以避免这种要求。
然而,许多人对1失去的信息是,在许多方面应该只有一个或许没有对象。