如何在TypeORM与NestJS中为查询方法添加分页功能?
分页功能改造方案
核心改动点
- 替换字符串拼接的SQL写法,改用参数化查询规避SQL注入风险
- 在查询语句中添加
LIMIT和OFFSET实现分页逻辑,每次返回指定条数的记录 - 单独执行
COUNT(*)查询获取总记录数,替代原有的supplier.length,提升大数据量下的性能 - 复用Pagination类的默认值,处理
page和limit参数未传入的场景
修改后的完整代码
public async allSuppliersForBid( filter: FilterSupplierDto, ): Promise<[Supplier[], number]> { // 提取分页参数,默认值与Pagination类保持一致 const { limit = 10, page = 1, query = '' } = filter; // 计算分页偏移量:(当前页码-1) * 每页条数 const offset = (page - 1) * limit; // 执行分页查询(参数化写法,避免SQL注入) const suppliers = await this.supplierRepos.query( `SELECT * FROM suppliers WHERE (suppliers."fullName" ILIKE $1 OR suppliers."companyName" ILIKE $1 OR suppliers.phone LIKE $2) AND suppliers.status = 'active' AND suppliers."isVerified" = 'true' AND suppliers."isEnabled" = 'true' AND "assignCluster" <> '{}'::jsonb LIMIT $3 OFFSET $4`, [`%${query}%`, `%${query}%`, limit, offset] ); // 单独查询总记录数(复用WHERE条件,保证计数准确) const countResult = await this.supplierRepos.query( `SELECT COUNT(*) FROM suppliers WHERE (suppliers."fullName" ILIKE $1 OR suppliers."companyName" ILIKE $1 OR suppliers.phone LIKE $2) AND suppliers.status = 'active' AND suppliers."isVerified" = 'true' AND suppliers."isEnabled" = 'true' AND "assignCluster" <> '{}'::jsonb`, [`%${query}%`, `%${query}%`] ); const count = parseInt(countResult[0].count, 10); return [suppliers, count]; }
额外注意事项
- 确认
FilterSupplierDto已经继承了Pagination类,这样page和limit参数会自动应用校验规则和默认值 - PostgreSQL中
ILIKE是大小写不敏感的匹配,LIKE是大小写敏感的,根据你的业务需求保留即可 - 总记录数查询复用了和分页查询完全一致的WHERE条件,确保计数结果和分页数据的筛选逻辑一致
内容的提问来源于stack exchange,提问作者Mehdi Hassan Jony
相关产品推荐
相关产品推荐

