一篇博客可以有多个标签,而一个标签可以使用在多篇博客上,Blog
类和Tag
类是典型的多对多关系。
@ManyToMany
用以表示多对多关系,与@OneToOne
和@ManyToOne
一样,也可以有单向和双向关系之分。
是单向还是双向,和标注本身并没有关系,只是看实体类之间是否相互引用。
下面的代码定义了Blog
到Tag
的单向多对多关系,所有操作都设置为级联的。
@Entity
public class Blog {
@ManyToMany(cascade = CascadeType.ALL)
private List<Tag> tags = new ArrayList<Tag>();
}
如果在Tag
中定义一个Blog
集合,则形成双向关系:
@Entity
public class Tag {
@ManyToMany(mappedBy = “tags”)
private List<Blog> blogs = new ArrayList<Blog>();
}
mappedBy = "tag"
表示,当前类(Tag
)是通过Blog
中tags
属性与之建立关联的。Blog
是关系维护方,Tag
类是关系被维护方。
多对多关系的定义如果自动生成DDL,则会生成一张描述多对多关系的表,在这个例子中表明为blog_tag
,表中的两个属性分别会命名为blog_id
和tag_id
。
如果需要指定表名和属性名,即基于自动映射的命名规则生成的Schema相关命名,和实际命名不相同时,则需要使用@JoinTable
标注,如:
@Entity
public class Blog {
@ManyToMany(cascade = CascadeType.ALL)
@JoinTable(
name="blog_tag_relation",
joinColumns=@JoinColumn(name="blog_id", referencedColumnName="id"),
inverseJoinColumns=@JoinColumn(name="tag_id", referencedColumnName="id")
)
private List<Tag> tags = new ArrayList<Tag>();
}
在实际情况下,我们建立多对多关系的同时还需要存储一些其他信息,例如该关系的创建时间,此时,我们可以将多对多关系分解为两个多对一关系。
定义一个BlogTag
实体类来表示Blog
与Tag
之间的多对多关系:
@Entity
class BlogTag {
@ManyToOne
private Blog blog;
@ManyToOne
private Tag tag;
private Date createdTime;
}
让BlogTag
这个实体类建立与Blog
和Tag
的多对一关系:
登录发表评论 登录 注册