单向一对多关联
如果您将@OneToMany 注释与@JoinColumn 一起使用,那么您就有一个单向关联,就像下图中的父Post 实体和子PostComment 之间的关联:
当使用单向一对多关联时,只有父方映射关联。
在此示例中,只有 Post 实体将定义与子 PostComment 实体的 @OneToMany 关联:
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
@JoinColumn(name = "post_id")
private List<PostComment> comments = new ArrayList<>();
双向一对多关联
如果将@OneToMany 与mappedBy 属性集一起使用,则具有双向关联。在我们的例子中,Post 实体都有一个PostComment 子实体的集合,而子PostComment 实体有一个对父Post 实体的引用,如下图所示:
在PostComment实体中,post实体属性映射如下:
@ManyToOne(fetch = FetchType.LAZY)
private Post post;
我们将fetch 属性显式设置为FetchType.LAZY 的原因是,默认情况下,所有@ManyToOne 和@OneToOne 关联都会被急切地获取,这可能会导致N+1 查询问题。
在Post实体中,comments关联映射如下:
@OneToMany(
mappedBy = "post",
cascade = CascadeType.ALL,
orphanRemoval = true
)
private List<PostComment> comments = new ArrayList<>();
@OneToMany 注释的mappedBy 属性引用子PostComment 实体中的post 属性,这样,Hibernate 就知道双向关联是由@ManyToOne 方控制的,即负责管理此表关系所基于的外键列值。
对于双向关联,您还需要有两个实用方法,例如addChild 和removeChild:
public void addComment(PostComment comment) {
comments.add(comment);
comment.setPost(this);
}
public void removeComment(PostComment comment) {
comments.remove(comment);
comment.setPost(null);
}
这两种方法确保双向关联的双方是同步的。如果不同步两端,Hibernate 不保证关联状态更改会传播到数据库。
选择哪一个?
单向@OneToMany 关联的性能不是很好,所以你应该避免它。
你最好使用双向@OneToMany,效率更高。