ManyToManyView
经典ORM关联的不足
在基础映射/关联映射中,我们学习了ORM中经典的关联映射,包括一对一、多对一、一对多和多对多。
然而,有一种场景,映射模式的选择让人很纠结。为了展示这种场景,从熟悉的场景开始。
无争议的多对多关联
让我们来看一段DDL
create table book(
...略...
)engine=innodb;;
create table author(
...略...
) engine=innodb;
/* highlight-next-line */
create table book_author_mapping(
book_id bigint unsigned not null,
author_id bigint unsigned not null
) engine=innodb;
alter table book_author_mapping
add constraint pk_book_author_mapping
primary key(book_id, author_id)
;
alter table book_author_mapping
add constraint fk_book_author_mapping__book
foreign key(book_id)
references book(id)
on delete cascade
;
alter table book_author_mapping
add constraint fk_book_author_mapping__author
foreign key(author_id)
references author(id)
on delete cascade
;
这段DDL中,book_author_mapping
表很特殊,只有两个外键,一个指向book
表,一个指向author
表。这种只有两个外键的子表用于表达两个父表之间的多对多关联。
ORM的多对多映射会隐藏中间表,即,中间表没有对应的Java/Kotlin实体类型。因此,中间表并不需要独立主键,而是直接使用两个外键作为联合主键。
信息
除了两个关联外键外,中间表不得具备其他任何字段,这是ORM中多对多关联的限制
ORM中对应的多对多关联如下:
-
主动方:
Book.authors
- Java
- Kotlin
Book.java@Entity
public interface Book {
@ManyToMany
List<Author> authors();
...省略其他代码...
}Book.kt@Entity
interface Book {
@ManyToMany
val authors: List<Author>
...省略其他代码...
} -
从动方 (可选):
Author.books
- Java
- Kotlin
Author.java@Entity
public interface Author {
@ManyToMany(mappedBy = "authors")
List<Book> books();
...省略其他代码...
}Author.kt@Entity
interface Author {
@ManyToMany(mappedBy = "authors")
val books: List<Book>
...省略其他代码...
}