如何在NestJS+TypeORM中实现多对多关联查询?
解决方案
你可以通过以下几种方式实现需求:
方式一:利用实体关联查询
通过查询指定ID的B实体并加载其关联的A集合,TypeORM会自动处理中间表的关联逻辑:
import { Injectable } from '@nestjs/common'; import { InjectRepository } from '@nestjs/typeorm'; import { Repository } from 'typeorm'; import { B } from './entities/B.entity'; import { A } from './entities/A.entity'; @Injectable() export class YourService { constructor( @InjectRepository(B) private readonly bRepository: Repository<B>, ) {} async getAsByBId(given_B_id: number): Promise<A[]> { const targetB = await this.bRepository.findOne({ where: { id: given_B_id }, // 若B实体的AObjects未设置eager: true,需显式指定relations加载关联 relations: ['AObjects'], }); return targetB?.AObjects || []; } }
方式二:使用QueryBuilder直接映射原生SQL
这种方式完全对应你给出的原生SQL,直接操作中间表和A表的关联:
import { Injectable } from '@nestjs/common'; import { InjectRepository } from '@nestjs/typeorm'; import { Repository } from 'typeorm'; import { A } from './entities/A.entity'; @Injectable() export class YourService { constructor( @InjectRepository(A) private readonly aRepository: Repository<A>, ) {} async getAsByBId(given_B_id: number): Promise<A[]> { return this.aRepository .createQueryBuilder('A') .innerJoin('AB', 'ab', 'ab.Aid = A.id') .where('ab.Bid = :bid', { bid: given_B_id }) .getMany(); } }
方式三:通过实体关联的QueryBuilder查询
无需硬编码中间表名,利用TypeORM的实体关联关系构建查询,维护性更强:
import { Injectable } from '@nestjs/common'; import { InjectRepository } from '@nestjs/typeorm'; import { Repository } from 'typeorm'; import { A } from './entities/A.entity'; @Injectable() export class YourService { constructor( @InjectRepository(A) private readonly aRepository: Repository<A>, ) {} async getAsByBId(given_B_id: number): Promise<A[]> { return this.aRepository .createQueryBuilder('A') .innerJoin('A.BObjects', 'b') .where('b.id = :bid', { bid: given_B_id }) .getMany(); } }
注意事项
- 你的实体关联配置是正确的:双向多对多仅需在其中一方(这里是B实体)添加
@JoinTable装饰器,另一方(A实体)无需重复配置。 - 若不需要默认加载关联数据,建议将B实体的
AObjects的eager: true移除,改为在查询时通过relations或QueryBuilder显式加载,避免不必要的性能开销。
内容的提问来源于stack exchange,提问作者sivan m
相关产品推荐
相关产品推荐

