如何在TypeORM中无需QueryBuilder实现带自定义条件的LEFT JOIN
在TypeORM中无需QueryBuilder实现获取所有医生及未来预约的需求
前提:实体定义
首先确保你的实体正确配置关联关系:
Doctor 实体
import { Entity, PrimaryColumn, Column, OneToMany } from "typeorm"; import { Appointment } from "./Appointment"; @Entity() export class Doctor { @PrimaryColumn() doc_id: string; @Column() doc_name: string; @OneToMany(() => Appointment, appointment => appointment.doctor) appointments: Appointment[]; }
Appointment 实体
import { Entity, PrimaryColumn, Column, ManyToOne, JoinColumn } from "typeorm"; import { Doctor } from "./Doctor"; @Entity() export class Appointment { @PrimaryColumn() app_id: string; @Column() app_day: Date; @Column() app_hour: string; @ManyToOne(() => Doctor, doctor => doctor.appointments) @JoinColumn({ name: "app_doc_id" }) doctor: Doctor; }
不使用QueryBuilder的查询写法
要实现获取所有医生(含无预约的)且仅加载未来N天的预约,核心是通过leftJoinAndSelect明确左连接,同时用$or条件过滤预约(要么符合未来时间,要么无预约)。以下是类似findBy风格的写法:
import { MoreThan, IsNull } from "typeorm"; import { Doctor } from "./entities/Doctor"; // 计算未来7天的日期,可按需调整天数 const futureDate = new Date(); futureDate.setDate(futureDate.getDate() + 7); // 执行查询 const doctors = await doctorRepository.find({ // 手动指定左连接并加载关联的预约数据 join: { alias: "doctor", leftJoinAndSelect: { appointments: "doctor.appointments", }, }, // 过滤逻辑:要么预约在未来,要么无任何预约 where: { $or: [ { appointments: { app_day: MoreThan(futureDate), }, }, { appointments: IsNull(), }, ], }, });
关键说明
- 左连接的必要性:通过
join.leftJoinAndSelect明确使用左连接,确保即使医生无符合条件的预约,也会被保留在结果中。 - 条件逻辑:
$or的两个分支分别覆盖两种情况——有未来预约的医生,以及无任何预约的医生,避免过滤掉无符合条件预约的医生。 - 结果处理:TypeORM会自动合并同一医生的多条关联记录,最终每个
Doctor对象的appointments数组仅包含符合条件的未来预约,无预约的医生该数组为空。
若需要包含当天的预约,将MoreThan替换为MoreThanOrEqual即可。
内容的提问来源于stack exchange,提问作者Arnaud Denoyelle
相关产品推荐
相关产品推荐

