如何在TypeORM/NestJS的findAll方法中实现分页功能?
TypeORM 分页功能实现方案
问题根源
你之前的代码混用了TypeORM的两种查询模式:
createQueryBuilder链式查询模式findAndCount选项式查询模式findAndCount的where参数要求传入查询条件对象,你传入query.getMany()的返回值(Promise数组)完全不符合参数要求,因此触发报错。
最优修改方案(复用现有QueryBuilder逻辑,改动最小)
你已经写好了动态where条件的QueryBuilder代码,不需要切换到findAndCount,直接在现有QueryBuilder基础上追加分页参数即可,修改后的完整findAll代码如下:
async findAll(queryCertificateDto: QueryCertificateDto, page = 1): Promise<PaginatedResult> { const { country, sponser } = queryCertificateDto; // 单页条数固定为10,可根据需求调整为参数传入 const pageSize = 10; const skip = (page - 1) * pageSize; const query = this.certificateRepository.createQueryBuilder('certificate'); if (sponser) { const upperSponser = sponser.toUpperCase(); query.andWhere('UPPER(certificate.sponser) = :sponser', { sponser: upperSponser }); } if (country) { const upperCountry = country.toUpperCase(); query.andWhere('UPPER(certificate.country) = :country', { country: upperCountry }); } // 追加分页参数,调用getManyAndCount直接获取[数据集, 总条数] const [certificates, total] = await query .skip(skip) .take(pageSize) .getManyAndCount(); // 组装符合PaginatedResult格式的返回值 return { data: certificates, meta: { total, page, last_page: Math.ceil(total / pageSize) } }; }
代码说明
skip计算规则:当前页码减1乘以单页条数,实现跳过前N页已查询的数据take对应单页返回条数,这里固定为10符合你的需求,也可以改成参数动态传入getManyAndCount是QueryBuilder提供的原生分页方法,一次查询同时返回符合条件的数据集和总记录数,不需要单独调用两次查询- 最后返回的结构完全匹配你定义的
PaginatedResult类要求,无需额外处理
可选方案:纯findAndCount实现
如果你想改用findAndCount的写法,也可以参考如下代码,无需使用QueryBuilder:
async findAll(queryCertificateDto: QueryCertificateDto, page = 1): Promise<PaginatedResult> { const { country, sponser } = queryCertificateDto; const pageSize = 10; const skip = (page - 1) * pageSize; const whereConditions = {}; if (sponser) { // 注意:如果用findAndCount做大写匹配,需要开启数据库的大小写不敏感,或者用ILike(PostgreSQL)/ Like配合UPPER函数 whereConditions['sponser'] = sponser.toUpperCase(); } if (country) { whereConditions['country'] = country.toUpperCase(); } const [certificates, total] = await this.certificateRepository.findAndCount({ where: whereConditions, skip, take: pageSize }); return { data: certificates, meta: { total, page, last_page: Math.ceil(total / pageSize) } }; }
注意:如果数据库字段是大小写敏感的,findAndCount写法需要额外调整匹配逻辑,更推荐第一种复用QueryBuilder的方案
内容的提问来源于stack exchange,提问作者Shruti sharma
相关产品推荐
相关产品推荐

