如何使用TypeORM QueryBuilder编写指定MySQL查询语句?
用TypeORM QueryBuilder实现目标MySQL查询
下面是对应你提供的原生SQL的QueryBuilder实现,分两种场景给出代码:
场景1:实体已配置关联关系
假设你的实体类(Client、Invoice、Item)已经正确配置了关联:
Client与Invoice是一对多关系(@OneToMany(() => Invoice, invoice => invoice.client))Invoice与Item是一对多关系(@OneToMany(() => Item, item => item.invoice))Invoice与Client、Item与Invoice分别配置了多对一反向关联
可以直接利用关联关系构建查询:
import { getRepository } from "typeorm"; import { Client } from "./entities/Client"; // 替换为你的实体路径 const result = await getRepository(Client) .createQueryBuilder("client") // 关联invoices表 .innerJoin("client.invoices", "invoices") // 关联items表 .innerJoin("invoices.items", "items") // 选择需要的字段,对应原生SQL的SELECT部分 .select([ "client.name", "items.invoiceId", `CONCAT(DAY(invoices.created_At), ' ', SUBSTR(MONTHNAME(invoices.created_At), 1, 3), ' ', YEAR(invoices.created_At)) AS Date` ]) // 按items.invoiceId分组,对应原生SQL的GROUP BY .groupBy("items.invoiceId") .getRawMany(); // 使用getRawMany获取原生格式的结果,和repo.query返回格式一致
场景2:未配置实体关联关系(手动指定join条件)
如果实体没有配置关联,或者需要手动指定关联逻辑,可以直接用表名和外键条件进行join:
import { getConnection } from "typeorm"; const result = await getConnection() .createQueryBuilder() // 从client表开始,指定别名 .select("client.name", "name") .addSelect("items.invoiceId", "invoiceId") .addSelect( `CONCAT(DAY(invoices.created_At), ' ', SUBSTR(MONTHNAME(invoices.created_At), 1, 3), ' ', YEAR(invoices.created_At))`, "Date" ) // 手动关联invoices表 .innerJoin("invoices", "invoices", "invoices.clientId = client.id") // 手动关联items表 .innerJoin("items", "items", "items.invoiceId = invoices.id") .from("client", "client") // 分组条件 .groupBy("items.invoiceId") .getRawMany();
关键说明
- 使用
getRawMany()可以确保返回结果的格式和this.repo.query()完全一致,都是键值对形式的原生结果 - 日期格式化的SQL表达式直接沿用了你原生查询中的写法,TypeORM会原样传递给MySQL执行
- 如果你的实体字段名和数据库列名有映射(比如实体用
createdAt,数据库是created_At),注意替换成对应名称即可
内容的提问来源于stack exchange,提问作者junnubhai
相关产品推荐
相关产品推荐

