runoops.com

TypeORM 多对多的关系并指定关系表

多对多是一种 A 包含多个 B 实例,而 B 包含多个 A 实例的关系。 我们以Question 和 Category 实体为例。 Question 可以有多个 categories, 每个 category 可以有多个 questions。

有如下表结构:

category:
+-------+--------------+------+-----+---------+----------------+
| Field | Type         | Null | Key | Default | Extra          |
+-------+--------------+------+-----+---------+----------------+
| id    | int(11)      | NO   | PRI | NULL    | auto_increment |
| name  | varchar(255) | NO   |     | NULL    |                |
+-------+--------------+------+-----+---------+----------------+

question:
+-------+--------------+------+-----+---------+----------------+
| Field | Type         | Null | Key | Default | Extra          |
+-------+--------------+------+-----+---------+----------------+
| id    | int(11)      | NO   | PRI | NULL    | auto_increment |
| title | varchar(255) | NO   |     | NULL    |                |
| text  | varchar(255) | NO   |     | NULL    |                |
+-------+--------------+------+-----+---------+----------------+

question_category_xref:
+-------------+---------+------+-----+---------+----------------+
| Field       | Type    | Null | Key | Default | Extra          |
+-------------+---------+------+-----+---------+----------------+
| id          | int(11) | NO   | PRI | NULL    | auto_increment |
| question_id | int(11) | NO   | MUL | NULL    |                |
| category_id | int(11) | NO   | MUL | NULL    |                |
+-------------+---------+------+-----+---------+----------------+

实体类:

import { Entity, PrimaryGeneratedColumn, Column, ManyToMany } from "typeorm";
import { Question } from "./Question";

@Entity()
export class Category {
  @PrimaryGeneratedColumn()
  id: number;

  @Column()
  name: string;

  @ManyToMany(() => Question, (question) => question.categories)
  questions: Question[]
}
import { Entity, PrimaryGeneratedColumn, Column, ManyToMany, JoinTable } from "typeorm";
import { Category } from "./Category";

@Entity()
export class Question {
  @PrimaryGeneratedColumn()
  id: number;

  @Column()
  title: string;

  @Column()
  text: string;

  @ManyToMany(() => Category, (category) => category.questions)
  // @JoinTable()
  // categories: Category[];

  @JoinTable({
    name: 'question_category_xref', //指定关系表
    joinColumn: {
      name: 'question_id',
      referencedColumnName: 'id',
    },
    inverseJoinColumn: {
      name: 'category_id',
      referencedColumnName: 'id',
    },
    synchronize:false  //此关系表不同步到数据库
  })
  categories: Category[];

}

我们只是创建了双向关系。 注意,反向关系没有@JoinTable。 @JoinTable必须只在关系的一边。并在@JoinTable中指定了关系表和关系字段。

双向关系允许您使用QueryBuilder从双方加入关系:

const categoriesWithQuestions = await connection
  .getRepository(Category)
  .createQueryBuilder("category")
  .leftJoinAndSelect("category.questions", "question")
  .getMany();

加入多对多关系:

const question = await connection.getRepository(Question).findOne({
        relations: {
            categories: true,
        },
        where: { id: 1 }
    });

const category = await AppDataSource.getRepository(Category).findOne({
        relations: {
            questions: true,
        },
        where: { id: 1 }
    })

Captcha Code

0 笔记

分享笔记

Inline Feedbacks
View all notes