如何让FindOptionsWhere支持区分Undefined与Null的默认查询
解决TypeORM中
findOneBy区分undefined和null查询的问题 问题现状
使用TypeORM的findOneBy方法时,传入{ status: undefined }和{ status: null }都会生成全表查询:
repo.findOneBy({ status: undefined }) repo.findOneBy({ status: null })
对应的SQL均为:
SELECT * FROM user
我们需要实现的效果:
- 传入
status: undefined时,不添加该查询条件,保留全表查询 - 传入
status: null时,生成WHERE status = null的过滤查询
可行解决方案
1. 提前过滤对象中的undefined属性
在把参数传给findOneBy之前,手动剔除值为undefined的键,让null保留下来参与查询:
// 封装工具函数清理查询参数 const cleanQueryParams = (params) => { return Object.fromEntries( Object.entries(params).filter(([_, val]) => val !== undefined) ); }; // 使用示例 // 传undefined的情况 const query1 = cleanQueryParams({ status: undefined }); repo.findOneBy(query1); // 生成 SELECT * FROM user // 传null的情况 const query2 = cleanQueryParams({ status: null }); repo.findOneBy(query2); // 生成 SELECT * FROM user WHERE status = null
2. 用QueryBuilder直接构建查询
如果需要更精细的逻辑控制,直接使用QueryBuilder可以明确区分两种场景:
async function findUser(status) { const qb = repo.createQueryBuilder('user'); // 仅当status不是undefined时,添加查询条件 if (status !== undefined) { qb.where('user.status = :status', { status }); } return qb.getOne(); } // 调用示例 findUser(undefined); // 执行全表查询 findUser(null); // 执行带status=null的过滤查询
3. 封装自定义Repository方法(适合高频使用场景)
如果这个查询逻辑在项目中频繁出现,可以给实体写个自定义Repository,把逻辑封装复用:
// user.repository.js import { Repository, EntityRepository } from 'typeorm'; import { User } from './user.entity'; @EntityRepository(User) export class UserRepository extends Repository { async findOneWithStatusFilter(status) { const qb = this.createQueryBuilder('user'); if (status !== undefined) { qb.where('user.status = :status', { status }); } return qb.getOne(); } } // 使用示例 userRepo.findOneWithStatusFilter(undefined); // 全表查询 userRepo.findOneWithStatusFilter(null); // 过滤status为null的记录
内容的提问来源于stack exchange,提问作者seepine
相关产品推荐
相关产品推荐

