ORM 映射中的“拥有方”是什么?

2022-08-31 06:50:20

拥有方究竟是什么意思?什么是解释与一些映射示例(一对多,一对一,多对一)?

以下文本摘自 Java EE 6 文档中对@OneToOne的描述。你可以看到其中的概念拥有面

定义与具有一对一多重性的另一个实体的单值关联。通常不需要显式指定关联的目标实体,因为它通常可以从被引用对象的类型中推断出来。如果关系是双向的,则非拥有方必须使用 OneToOne 批注的 mappedBy 元素来指定拥有方的关系字段或属性。


答案 1

为什么拥有方的概念是必要的:

双向关系的拥有方的想法来自这样一个事实,即在关系数据库中没有像对象那样的双向关系。在数据库中,我们只有单向关系 - 外键。

“拥有方”这个名字的原因是什么?

Hibernate 跟踪的关系的拥有方是拥有数据库中外键的关系的一方。

拥有方的概念解决了什么问题?

以两个实体为例,该实体在没有声明拥有方的情况下映射:

@Entity
@Table(name="PERSONS")
public class Person {
    @OneToMany
    private List<IdDocument>  idDocuments;
}

@Entity
@Table(name="ID_DOCUMENTS")
public class IdDocument {
    @ManyToOne
    private Person person;
}

从 OO 的角度来看,此映射定义的不是一个双向关系,而是个单独的单向关系。

映射不仅会创建表和 ,还会创建第三个关联表:PERSONSID_DOCUMENTSPERSONS_ID_DOCUMENTS

CREATE TABLE PERSONS_ID_DOCUMENTS
(
  persons_id bigint NOT NULL,
  id_documents_id bigint NOT NULL,
  CONSTRAINT fk_persons FOREIGN KEY (persons_id) REFERENCES persons (id),
  CONSTRAINT fk_docs FOREIGN KEY (id_documents_id) REFERENCES id_documents (id),
  CONSTRAINT pk UNIQUE (id_documents_id)
)

请注意,仅 打开 主键。在这种情况下,Hibernate 独立跟踪关系的两端:如果将文档添加到关系中,则会在关联表中插入一条记录。pkID_DOCUMENTSPerson.idDocumentsPERSON_ID_DOCUMENTS

另一方面,如果我们调用 ,我们将外键person_id更改为表 。休眠在数据库上创建个单向(外键)关系,以实现一个双向对象关系。idDocument.setPerson(person)ID_DOCUMENTS

拥有方的概念如何解决问题:

很多时候,我们想要的只是表上的一个外键,而不是额外的关联表。ID_DOCUMENTSPERSONS

为了解决这个问题,我们需要配置Hibernate以停止跟踪关系上的修改。休眠应该只跟踪关系的另一边,为此,我们添加了mappedByPerson.idDocumentsIdDocument.person

@OneToMany(mappedBy="person")
private List<IdDocument>  idDocuments;

这是什么意思 映射由 ?

这意味着:“关系这一侧的修改已经由关系的另一端IdDocument.person映射,因此无需在额外的表中单独跟踪它。

是否有任何GOTCHA,后果?

使用mappedBy,如果我们只调用,则外键中的外键将不会链接到新文档,因为这不是关系的拥有/跟踪的一侧!person.getDocuments().add(document)ID_DOCUMENTS

要将文档链接到新用户,您需要显式调用 ,因为这是关系的拥有方document.setPerson(person)

使用mapredBy时,开发人员有责任知道什么是拥有方,并更新关系的正确端,以触发数据库中新关系的持久性。


答案 2

您可以想象,拥有方是具有对另一方的引用的实体。在你的摘录中,你有一个一对一的关系。由于它是一种对称关系,因此如果对象A与对象B相关,那么您最终会得到它,反之亦然。

这意味着将对对象 B 的引用保存到对象 A 中,而将对对象 B 的引用保存到对象 A 中将是多余的:这就是为什么您选择哪个对象“拥有”另一个对象对它的引用。

当您拥有一对多关系时,与“许多”部分相关的对象将是拥有方,否则您将不得不存储从单个对象到多个对象的许多引用。为了避免这种情况,第二个类中的每个对象都将有一个指向它们所引用的单个对象的指针(因此它们是拥有方)。

对于多对多关系,由于您将需要一个单独的映射表,因此不会有任何拥有方。

总之,拥有方是具有对另一方有参考的实体。


推荐