单向一对多关联
如果你使用@OneToMany注释和@JoinColumn,那么你就有一个单向的关联,就像下图中父Post实体和子PostComment之间的关联一样:
当使用单向一对多关联时,只有父端映射该关联。
在这个例子中,只有Post实体定义了与子PostComment实体的@OneToMany关联:
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
@JoinColumn(name = "post_id")
private List<PostComment> comments = new ArrayList<>();
双向一对多关联
如果您使用带有mappedBy属性集的@OneToMany,那么您就有了一个双向关联。在我们的例子中,Post实体都有一个PostComment子实体的集合,并且子PostComment实体有一个指向父Post实体的引用,如下图所示:
在PostComment实体中,post实体属性映射如下:
@ManyToOne(fetch = FetchType.LAZY)
private Post post;
我们显式地将fetch属性设置为FetchType的原因。LAZY是因为默认情况下,所有的@ManyToOne和@OneToOne关联都是急切获取的,这可能会导致N+1个查询问题。
在Post实体中,评论关联映射如下:
@OneToMany(
mappedBy = "post",
cascade = CascadeType.ALL,
orphanRemoval = true
)
private List<PostComment> comments = new ArrayList<>();
@OneToMany注释的mappedBy属性引用子PostComment实体中的post属性,通过这种方式,Hibernate知道双向关联是由@ManyToOne控制的,它负责管理这个表关系所基于的外键列值。
对于双向关联,你还需要有两个实用工具方法,比如addChild和removecchild:
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。