TypeORM+PostgreSQL多对多关系:查询关联指定用户的目标公司
TypeORM + PostgreSQL 多对多关联条件查询实现方案
需求背景
公司与用户为多对多关系,对应三张表:
Company(id, name):公司表User(id, name):用户表User_Company(userId, companyId):关联中间表
需要实现按公司名称模糊匹配+关联指定用户ID的查询,返回结构为包含公司基本信息及该公司所有关联用户的数组。
实现步骤
1. 定义实体类
在TypeORM中配置多对多关联,指定已有的中间表:
Company 实体
import { Entity, PrimaryGeneratedColumn, Column, ManyToMany, JoinTable } from "typeorm"; import { User } from "./User"; @Entity('Company') export class Company { @PrimaryGeneratedColumn() id: number; @Column() name: string; @ManyToMany(() => User, user => user.companies) @JoinTable({ name: 'User_Company', // 指定中间表名 joinColumn: { name: 'companyId', referencedColumnName: 'id' }, inverseJoinColumn: { name: 'userId', referencedColumnName: 'id' } }) users: User[]; }
User 实体
import { Entity, PrimaryGeneratedColumn, Column, ManyToMany } from "typeorm"; import { Company } from "./Company"; @Entity('User') export class User { @PrimaryGeneratedColumn() id: number; @Column() name: string; @ManyToMany(() => Company, company => company.users) companies: Company[]; }
2. 编写查询逻辑
推荐使用QueryBuilder实现,灵活性更高且能精准控制关联逻辑:
import { getRepository } from "typeorm"; import { Company } from "./entities/Company"; // 查询函数:参数为公司名称关键词、用户ID async function queryCompanies(companyNameKeyword: string, targetUserId: number) { const companyRepo = getRepository(Company); const result = await companyRepo.createQueryBuilder('company') // 内连接用户表,确保只返回关联了目标用户的公司 .innerJoin('company.users', 'targetUser', 'targetUser.id = :userId', { userId: targetUserId }) // 模糊匹配公司名称 .andWhere('company.name LIKE :name', { name: `%${companyNameKeyword}%` }) // 加载该公司所有关联的用户列表 .leftJoinAndSelect('company.users', 'allUsers') // 去重,避免同一公司因关联多个用户重复返回 .distinct(true) .getMany(); return result; } // 调用示例:查询名称含"Apple"且关联用户ID为1的公司 queryCompanies('Apple', 1).then(res => console.log(JSON.stringify(res, null, 2)));
也可以使用Repository的find方法简化实现(部分TypeORM版本需确保关联条件解析正确):
import { getRepository, Like } from "typeorm"; import { Company } from "./entities/Company"; async function queryCompanies(companyNameKeyword: string, targetUserId: number) { const companyRepo = getRepository(Company); return await companyRepo.find({ relations: ['users'], where: { name: Like(`%${companyNameKeyword}%`), users: { id: targetUserId } } }); }
3. 结果说明
上述查询返回的结果结构完全符合需求:每个公司对象包含id、name字段,以及该公司所有关联用户的users数组,数组内为用户的id和name信息。
内容的提问来源于stack exchange,提问作者vanna
相关产品推荐
相关产品推荐

