表关系与实体关系
在关系数据库系统中,表关系分为三种类型:
- 一对多(通过外键列)
- 一对一(通过共享主键)
- 多对多(通过带有两个外键引用两个单独父表的链接表)
So, a one-to-many
表关系如下所示:
请注意,该关系基于post_id
子项中的外键列post_comment
table.
因此,在管理数据时,外键列是唯一的事实来源one-to-many
表关系。
现在,我们采用一个双向 JPA 实体关系来映射one-to-many
我们之前看到的表关系:
如果您看一下上图,您会发现有两种方法可以管理这种关系。
In the Post
实体,你有comments
收藏:
@OneToMany(
mappedBy = "post",
cascade = CascadeType.ALL,
orphanRemoval = true
)
private List<PostComment> comments = new ArrayList<>();
并且,在PostComment
, the post
关联映射如下:
@ManyToOne(
fetch = FetchType.LAZY
)
@JoinColumn(name = "post_id")
private Post post;
因此,您有两个可以更改实体关联的方面:
- 通过在
comments
儿童收藏,新post_comment
行应该与父行相关联post
实体通过其post_id
column.
- 通过设置
post
的财产PostComment
实体,即post_id
列也应该更新。
由于有两种方法来表示外键列,因此在将关联状态更改转换为其等效的外键列值修改时,您必须定义哪种方法是真实来源。
MappedBy(又称反面)
The mappedBy
属性告诉我们@ManyToOne
side 负责管理外键列,并且该集合仅用于获取子实体并将父实体状态更改级联到子实体(例如,删除父实体也应该删除子实体)。
它被称为反面因为它引用管理此表关系的子实体属性。
同步双向关联的双方
现在,即使您定义了mappedBy
属性和子端@ManyToOne
关联管理外键列,您仍然需要同步双向关联的双方。
最好的方法是添加这两个实用方法:
public void addComment(PostComment comment) {
comments.add(comment);
comment.setPost(this);
}
public void removeComment(PostComment comment) {
comments.remove(comment);
comment.setPost(null);
}
The addComment https://vladmihalcea.com/jpa-hibernate-synchronize-bidirectional-entity-associations/ and removeComment https://vladmihalcea.com/jpa-hibernate-synchronize-bidirectional-entity-associations/方法确保双方同步。因此,如果我们添加一个子实体,则子实体需要指向父实体,并且父实体应该将子实体包含在子集合中。