能否使用TypeORM QueryBuilder编写SQL Dialect无关的指定查询?
问题解答
可以实现,TypeORM 的 QueryBuilder 原生支持嵌套子查询逻辑,生成的语句会自动适配你配置的数据库方言,不需要针对 MySQL、PostgreSQL、SQLite 等不同数据库做额外调整。
以下是对应实现代码:
TypeORM 0.2.x 版本写法
import { getRepository } from 'typeorm'; // 你的实体类,对应mytable表 import { MyTable } from './entity/MyTable'; // 构造子查询:查询mycol1='foo'对应的最大mycol2值 const subQuery = getRepository(MyTable) .createQueryBuilder('sub') .select('MAX(sub.mycol2)', 'maxCol2') .where('sub.mycol1 = :searchVal', { searchVal: 'foo' }); // 主查询 const result = await getRepository(MyTable) .createQueryBuilder('main') .where('main.mycol1 = :searchVal', { searchVal: 'foo' }) .andWhere(`main.mycol2 = (${subQuery.getQuery()})`) // 同步子查询的绑定参数,避免重复声明和SQL注入风险 .setParameters(subQuery.getParameters()) .getMany();
TypeORM 0.3.x 版本写法
0.3.x 版本废弃了getRepository全局方法,改用 DataSource 初始化实例调用:
// 你初始化的DataSource实例 import { AppDataSource } from './data-source'; import { MyTable } from './entity/MyTable'; const myTableRepo = AppDataSource.getRepository(MyTable); const subQuery = myTableRepo .createQueryBuilder('sub') .select('MAX(sub.mycol2)') .where('sub.mycol1 = :searchVal', { searchVal: 'foo' }); const result = await myTableRepo .createQueryBuilder('main') .where('main.mycol1 = :searchVal', { searchVal: 'foo' }) .andWhere(`main.mycol2 = ${subQuery.getQuery()}`) .setParameters(subQuery.getParameters()) .getMany();
注意事项
- 所有查询参数通过
:参数名的形式绑定,不要直接拼接字符串,避免SQL注入风险 - 子查询使用
getQuery()获取占位符形式的SQL片段,再通过setParameters同步参数,能保证跨方言兼容性 - 最终执行的SQL和你给出的原生SQL结构完全一致,没有额外冗余逻辑
内容的提问来源于stack exchange,提问作者Platus
相关产品推荐
相关产品推荐

