在本课中,我们将学习如何使用连接表实现多对多的关系。
每项赛事都有一些比赛类别,如男子和/或女士的单打和双打。此外,所有四个大满贯赛事都有混合双打类别。其他不太知名的类别是轮椅网球和沙滩网球。这种情况很适合多对多的关系,即许多类别都是锦标赛的一部分,许多锦标赛都有相同的比赛类别。
一个比赛有很多类别,一个类别包含在很多比赛中。
我们已经在之前的一课中创建了Tournament
类。在这一课中,我们将创建Category
类,然后用多对多的关系将二者连接起来。在数据库中,这种关系是用一个连接表来建模的,该表在关系中拥有两个表的主键。
多对多的关系是用一个连接表来实现的。
我们还将模拟两个现实生活中的约束。
manytomany
,并将bi
包中的所有文件复制到onetomany
包内。这些文件包括Player
、PlayerProfile
、Registration
和Tournament
类以及相关的数据接入层、服务层和控制器类。我们将首先在io.datajek.databaseelationships.manytomany
包中创建一个新类,Category
。这个类有两个字段,id
和name
,其中id
是主键。由于我们不希望相同的类别名称出现一次以上,我们将使用@Column
注解的unique
属性来施加唯一键约束。
package io.datajek.databaserelationships.manytomany;
@Entity
public class Category {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private int id;
@Column(unique=true)
private String name;
//constructors
//getters and setters
}
@Column(unique=true)
确保同一类别名称不会被多次输入。
对于多对多的关系,任何一方都可以成为所有者。这取决于业务规则是如何定义的。比方说,我们不能有一个没有附加类别的锦标赛,但我们可以有一个不与任何锦标赛相关联的类别。考虑到这种情况,一个类别可以单独存在,但一个锦标赛需要有一个或多个类别与之关联。所以,Category
成为拥有方,Tournament
成为被引用方。
在一个单向的多对多的关系中,我们把关系放在子方。所以,在Tournament
类中,我们必须放一个指向Category
类的链接。由于一个锦标赛可以有不止一个类别,我们将创建一个Category
的List
,如下所示。
@Entity
public class Tournament {
//...
private List<Category> playingCategories = new ArrayList<>();
//...
}
为这个字段创建一个getter
和setter
方法。
@ManyToMany
注解被用来在两个实体之间创建多对多的关系。
@ManyToMany
private List<Category> playingCategories = new ArrayList<>();
多对多的关系与我们到目前为止看到的关系不同。在这里,外键被存储在一个单独的表中,称为连接表,而不是放在父表或子表中。连接表连接两个表并包含两个表的外键。锦标赛和类别表不包含彼此的键,而是这两个表的主键都在连接表中。
joinColumns
和inverseJoinColumns