NestJS中如何查询、修改多对多字段及填充关联中间表数据
NestJS + TypeORM 多对多关联操作指南
前置说明
你当前的实体定义是正确的,@JoinTable 标注在Author实体上,说明Author是多对多关联的拥有方,自动生成的authors_books_books中间表是TypeORM默认命名规则生成的,所有关联操作都可以通过ORM方法完成,无需手动写SQL操作中间表。
1. 新增关联关系(写入中间表数据)
有两种常用实现方式:
方式1:实体关联赋值后保存
适合需要同时操作实体其他字段的场景:
// 1. 分别查询目标作者(id=x)和目标书籍(id=y) const targetAuthor = await this.authorRepository.findOneBy({ id: x }); const targetBook = await this.bookRepository.findOneBy({ id: y }); // 2. 把书籍追加到作者的关联书籍数组中 targetAuthor.books = [...(targetAuthor.books ?? []), targetBook]; // 3. 保存作者实体,TypeORM会自动在中间表写入关联数据 await this.authorRepository.save(targetAuthor);
方式2:QueryBuilder直接操作关联
无需提前查询两个实体,性能更高,适合仅需要新增关联的场景:
await this.authorRepository .createQueryBuilder() .relation(Author, 'books') .of(x) // 填入作者id .add(y); // 填入要关联的书籍id,支持传入数组批量关联多本书籍
2. 多对多关联查询
基础关联查询
查询实体时附带加载关联数据:
// 查询id为x的作者,同时返回他关联的所有书籍 const authorWithBooks = await this.authorRepository.findOne({ where: { id: x }, relations: ['books'] // 指定要加载的关联字段 }); // 直接通过 authorWithBooks.books 即可拿到关联的书籍列表
带条件的关联查询
使用QueryBuilder实现更灵活的过滤:
// 查询id为x的作者,仅返回标题包含“NestJS”的关联书籍 const authorWithFilteredBooks = await this.authorRepository .createQueryBuilder('author') .leftJoinAndSelect('author.books', 'book') .where('author.id = :authorId', { authorId: x }) .andWhere('book.title LIKE :keyword', { keyword: '%NestJS%' }) .getOne();
3. 关联关系变更
移除指定关联
直接删除中间表对应关联记录,不影响原作者和书籍实体:
// 移除作者x和书籍y的关联 await this.authorRepository .createQueryBuilder() .relation(Author, 'books') .of(x) .remove(y); // 支持传入数组批量移除多个关联
全量覆盖关联
清空原有关联,替换为新的关联列表:
import { In } from 'typeorm'; // 1. 查询目标作者 const targetAuthor = await this.authorRepository.findOneBy({ id: x }); // 2. 查询需要新关联的书籍列表(示例:id为y3、y4的书籍) const newRelatedBooks = await this.bookRepository.findBy({ id: In([y3, y4]) }); // 3. 直接覆盖关联数组后保存 targetAuthor.books = newRelatedBooks; await this.authorRepository.save(targetAuthor); // 操作完成后,中间表中该作者原来的关联会被自动删除,仅保留新的关联
内容的提问来源于stack exchange,提问作者lvyecle
相关产品推荐
相关产品推荐

