Hibernate 休眠-为什么使用多对一来表示一对一?

Hibernate 休眠-为什么使用多对一来表示一对一?,hibernate,orm,Hibernate,Orm,我见过人们使用多对一映射来表示一对一的关系。我也在加文·金的一本书和一些文章中读到了这一点 例如,如果一个客户只能有一个配送地址,而配送地址只能属于一个客户,则映射如下所示: <class name="Customer" table="CUSTOMERS"> ... <many-to-one name="shippingAddress" class="Address" column="SHIPP

我见过人们使用多对一映射来表示一对一的关系。我也在加文·金的一本书和一些文章中读到了这一点

例如,如果一个客户只能有一个配送地址,而配送地址只能属于一个客户,则映射如下所示:

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

...
...
这本书的理由如下(引用它):

“你不在乎关联的目标端是什么,因此你可以将其视为一对一的关联,而不需要多个部分。”

我的问题是,为什么使用多对一而不是一对一?
一对一
是什么让它成为
多对一
不太理想的选择


谢谢。

它甚至出现在官方的Hibernate文档中:


这并非完全不合理。多对一端表示:我通过我的一列映射到-one端的ID。对于多对一,您将使用完全相同的数据库模式。

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


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

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

在后一种情况下,hibernate映射方法是使用
多对一关联(允许指定外键)

原因很简单:你不在乎 目标侧的目标是什么 联想,所以你可以把它当作 一对一的协会,而不是许多 部分你想表达的只是“这个” 实体的属性是 对另一个实例的引用 实体”,并使用外键字段 代表这种关系


换句话说,使用
多对一
是映射一对一外键关联的方法(实际上可能比共享主键一对一关联更频繁)。

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


但是,多对1会丢失信息,即在多个边上应该只有一个或可能没有对象。

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

f、 e.如果您创建一个绑定到同名表的PersonAddress类,那么每个人将只有一个地址

  • 类别人员->属性:地址
  • 表人员->列:id、名称
  • 表地址->列:id,城市
使用多对一关系时,表结构略有变化,但可以达到相同的效果

  • 类别人员->属性:地址
  • 表人员->列:id、名称、, 地址ID(fk)
  • 表地址->列:id, 城市
……但更多。现在此人可以有多个地址:

  • 类别人员->属性:地址
  • 表人员->列:id、名称、, 地址ID(fk),发货地址ID(fk)
  • 表地址->列:id, 城市
两个外键(addressid和shippingaddressid)可以指向一个DB条目……或者一个地址可以属于2-3个人。所以从人的角度看是多对一,从地址的角度看是一对多

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

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

简而言之:

  • 一对一的输入或映射更难处理
  • 一对一有其局限性
  • 相反,使用多对一更灵活,同样的事情也可以通过

  • 您能否提供一个示例来阐明您关于映射“具有唯一约束的外键关系”的观点?既然这种关系在逻辑上是一对一的,为什么要在hibernate中将它映射为一对一呢?这似乎是什么时候的答案,但不是为什么…?不过,缺点是不能使用
    reverse=“true”
    。它不适用于多对一
    。您好,您知道如何用这种方式进行级联删除吗?