TypeORM 中如何优雅拼接 QueryBuilder 实现动态多条件查询
优化方案
TypeORM 的 QueryBuilder 实例支持分步链式调用,每次调用方法后都会返回实例本身,完全可以通过判断动态追加关联、条件语句,无需写大量分支判断。
最简优化写法
直接分步判断条件追加内容即可,代码量随条件线性增长,不会出现分支爆炸:
// 初始化基础查询构造器 const qb = this.userRepository.createQueryBuilder('user'); // 按需追加关联查询和筛选条件 if (option.productId) { qb.leftJoinAndSelect('user.products', 'product') .andWhere('product.id = :productId', { productId: option.productId }); } if (option.organizationId) { qb.leftJoinAndSelect('user.organization', 'organization') .andWhere('organization.id = :organizationId', { organizationId: option.organizationId }); } // 统一执行查询 const [tempResult, count] = await qb.getManyAndCount();
注意:不要多次调用
where方法,后续where会覆盖之前的条件,多条件拼接统一使用andWhere/orWhere即可,同时解决你原有代码中多条件同时存在时第一个筛选被覆盖的逻辑错误。
多条件批量处理方案
如果后续筛选条件较多,可以把条件封装为配置数组批量处理,扩展条件时只需新增配置项,无需修改逻辑代码:
// 条件配置,新增条件只需新增一项配置即可 const conditionConfig = [ { paramKey: 'productId', joinRelation: 'user.products', joinAlias: 'product', whereClause: 'product.id = :productId' }, { paramKey: 'organizationId', joinRelation: 'user.organization', joinAlias: 'organization', whereClause: 'organization.id = :organizationId' } ]; const qb = this.userRepository.createQueryBuilder('user'); const queryParams = {}; for (const config of conditionConfig) { const paramVal = option[config.paramKey]; if (paramVal) { qb.leftJoinAndSelect(config.joinRelation, config.joinAlias); qb.andWhere(config.whereClause); queryParams[config.paramKey] = paramVal; } } // 统一绑定参数 qb.setParameters(queryParams); const [tempResult, count] = await qb.getManyAndCount();
特殊场景说明
如果需要不管是否按关联表筛选,都返回关联表的数据,把对应的leftJoinAndSelect语句移到初始化qb的位置即可,不用放到if判断内。
内容的提问来源于stack exchange,提问作者hezf
相关产品推荐
相关产品推荐

