- 多对一/一对多的关系
多对一/一对多的关系
多对一/一对多是指 A 包含多个 B 实例的关系,但 B 只包含一个 A 实例。让我们以User 和 Photo 实体为例。User 可以拥有多张 photos,但每张 photo 仅由一位 user 拥有。
import { Entity, PrimaryGeneratedColumn, Column, ManyToOne } from "typeorm";import { User } from "./User";@Entity()export class Photo {@PrimaryGeneratedColumn()id: number;@Column()url: string;@ManyToOne(type => User, user => user.photos)user: User;}
import { Entity, PrimaryGeneratedColumn, Column, OneToMany } from "typeorm";import { Photo } from "./Photo";@Entity()export class User {@PrimaryGeneratedColumn()id: number;@Column()name: string;@OneToMany(type => Photo, photo => photo.user)photos: Photo[];}
这里我们将@ManyToOne添加到photos属性中,并将目标关系类型指定为Photo。你也可以在@ManyToOne /@OneToMany关系中省略@JoinColumn。没有@ManyToOne,@OneToMany就不可能存在。如果你想使用@OneToMany,则需要@ManyToOne。在你设置@ManyToOne的地方,相关实体将有”关联 id”和外键。
此示例将生成以下表:
+-------------+--------------+----------------------------+| photo |+-------------+--------------+----------------------------+| id | int(11) | PRIMARY KEY AUTO_INCREMENT || url | varchar(255) | || userId | int(11) | |+-------------+--------------+----------------------------++-------------+--------------+----------------------------+| user |+-------------+--------------+----------------------------+| id | int(11) | PRIMARY KEY AUTO_INCREMENT || name | varchar(255) | |+-------------+--------------+----------------------------+
如何保存这种关系:
const photo1 = new Photo();photo1.url = "me.jpg";await connection.manager.save(photo1);const photo2 = new Photo();photo2.url = "me-and-bears.jpg";await connection.manager.save(photo2);const user = new User();user.name = "John";user.photos = [photo1, photo2];await connection.manager.save(user);
或者你可以选择:
const user = new User();user.name = "Leo";await connection.manager.save(user);const photo1 = new Photo();photo1.url = "me.jpg";photo1.user = user;await connection.manager.save(photo1);const photo2 = new Photo();photo2.url = "me-and-bears.jpg";photo2.user = user;await connection.manager.save(photo2);
启用级联后,只需一次save调用即可保存此关系。
要在内部加载带有 photos 的 user,必须在FindOptions中指定关系:
const userRepository = connection.getRepository(User);const users = await userRepository.find({ relations: ["photos"] });// or from inverse sideconst photoRepository = connection.getRepository(Photo);const photos = await photoRepository.find({ relations: ["user"] });
或者使用QueryBuilder:
const users = await connection.getRepository(User).createQueryBuilder("user").leftJoinAndSelect("user.photos", "photo").getMany();// or from inverse sideconst photos = await connection.getRepository(Photo).createQueryBuilder("photo").leftJoinAndSelect("photo.user", "user").getMany();
通过在关系上启用预先加载,你不必指定关系或手动加入,它将始终自动加载。
