全书目录

第二十四篇:TypeORM 完全指南 —— 数据映射施工队宇宙

第五章:Relation —— 楼和楼之间的连廊、管线和挂接关系

1 分钟 274 字 第 437 / 962 个阅读单元

单表世界很快就不够用了。真实业务里一定有关系。

在施工队宇宙里,relation 就像:

  • 两栋楼之间的连廊
  • 地下管线的连接
  • 楼栋和楼栋的挂接规则

TypeORM 常见关系有四种:

text
@OneToOne
= 一对一

@ManyToOne
= 多对一

@OneToMany
= 一对多

@ManyToMany
= 多对多
#一个最常见的一对多例子:作者和文章
ts
import {
  Column,
  Entity,
  ManyToOne,
  OneToMany,
  PrimaryGeneratedColumn,
} from "typeorm";

@Entity({ name: "users" })
export class User {
  @PrimaryGeneratedColumn()
  id!: number;

  @Column()
  name!: string;

  @OneToMany(() => Post, (post) => post.author)
  posts!: Post[];
}

@Entity({ name: "posts" })
export class Post {
  @PrimaryGeneratedColumn()
  id!: number;

  @Column()
  title!: string;

  @ManyToOne(() => User, (user) => user.posts, { onDelete: "CASCADE" })
  author!: User;
}

它真正表达的是:

text
User 1 ───────── N Post

User.posts   = 从作者看,他有哪些文章
Post.author  = 从文章看,它属于谁
外键列        = 实际会落在 post 这一侧
#一定要记住谁握着外键

在很多 ORM 里,最容易迷糊的不是“有没有关系”,而是:

到底谁持有真实外键。

对一对多来说,通常是:

text
ManyToOne 那一侧,握着真实外键

也就是说:

text
Post 属于某个 User
=> post 表里通常有 userId 之类的列

不是 User.posts 真在数据库里有个数组列。


#查询关系的常见姿势
ts
const posts = await postRepository.find({
  relations: {
    author: true,
  },
});

或者:

ts
const users = await userRepository.find({
  relations: {
    posts: true,
  },
});

心智上要清楚:

text
relations = 让施工队顺着连廊把关联楼一起带回来

但也别养成“逢查必全带”的坏习惯。
关系不是越多越方便,而是越容易过度取数。