TypeORM/NestJS 中的分页

Posted

技术标签:

【中文标题】TypeORM/NestJS 中的分页【英文标题】:Pagination in TypeORM/NestJS 【发布时间】:2021-11-25 09:13:58 【问题描述】:

我必须在findAll() 方法中引入分页。我真的不知道该怎么做。我试过了,但它给出了很多错误。为此,我使用了typeorm 提供的findAndCount() 方法,但我不确定它是如何工作的。

截至目前,以下方法返回所有记录。我需要一次返回 10 条记录。请建议我需要做什么修改。

async findAll(queryCertificateDto: QueryCertificateDto,page=1):  Promise<PaginatedResult> 
    
    let  country, sponser  = queryCertificateDto;

    const query = this.certificateRepository.createQueryBuilder('certificate');

    if (sponser) 
        sponser = sponser.toUpperCase();
        query.andWhere('Upper(certificate.sponser)=:sponser',  sponser );
    

    if (country) 
        country = country.toUpperCase();
        query.andWhere('Upper(certificate.country)=:country',  country );
          
    const  certificates = query.getMany();     
    return certificates;

这是PaginatedResult 文件。

 export class PaginatedResult 
        data: any[];
        meta: 
          total: number;
          page: number;
          last_page: number;
        ;
      
  

我尝试更改 findAll() 的代码,但 where 子句给出错误。我不知道如何处理pagination 中的query.getMany()

 const take = query.take || 10
        const skip = query.skip || 0
       
      
        const [result, total] = await this.certificateRepository.findAndCount(
            
                where: query.getMany(),   //this is giving error
                take:take,
                skip:skip
            
        );
        return result;

我需要在这个方法中引入分页。任何帮助都会非常有帮助。

【问题讨论】:

where 子句通常用于提供条件。在您的情况下,query.getMany() 没有提供条件。 【参考方案1】:

Typeorm 有一个非常好的方法,专门针对您的用例 findAndCount

async findAll(queryCertificateDto: QueryCertificateDto):  Promise<PaginatedResult> 

    const take = queryCertificateDto.take || 10
    const skip = queryCertificateDto.skip || 0
    const country = queryCertificateDto.keyword || ''
    const sponser = queryCertificateDto.sponser || ''
    

    const query = this.certificateRepository.createQueryBuilder('certificate');

    const [result, total] = await this.certificateRepository.findAndCount(
        
            where:  country: Like('%' + country + '%') AND sponser: Like('%' + sponser + '%') , order:  name: "DESC" ,
            take: take,
            skip: skip
        
    );
     
    return 
        data: result,
        count: total
    ;

更多关于 Repository 类的文档可以找到here

【讨论】:

我只有 Tushar 在那里挣扎。你能指导我如何在我的代码中使用相同的方法吗?我已经放置了我尝试使用但有效的代码。我已经编辑了我的问题。【参考方案2】:

您不需要在最后一个代码中使用.getMany()where,结果是您需要的数据数组。

从您的第一个代码中,您可以这样做:

async findAll(queryCertificateDto: QueryCertificateDto,page=1): Promise<PaginatedResult> 
    // let's say limit and offset are passed here too
    let  country, sponser, limit, offset  = queryCertificateDto;

    const query = this.certificateRepository.createQueryBuilder('certificate');

    if (sponser) 
        sponser = sponser.toUpperCase();
        query.andWhere('certificate.sponser = :sponser',  sponser );
    

    if (country) 
        country = country.toUpperCase();
        query.andWhere('certificate.country = :country',  country );
    

    // limit and take mean the same thing, while skip and offset mean the same thing
    const certificates = await query
        .orderBy("certificate.id", "ASC")
        .limit(limit || 10)
        .offset(offset || 0)
        .getMany();

    // if you want to count just replace the `.getMany()` with `.getManyandCount()`;

    return certificates;
```

【讨论】:

谢谢。它每次只返回前 10 条记录。 不客气,如果您想要更多记录,只需将限制作为查询传递您需要的记录数,它将覆盖默认限制,即 10,默认值为 10 ,因此如果您不通过任何特定限制,它将返回 10 条记录。例如,如果您想要 40 条记录,并且您希望它从 11 的 id 开始,偏移量将为 10,限制为 40。简而言之,限制只是说我不想要更多这个数量的值,而偏移量是说跳过这个数量的记录并从这里开始。 因为数据库 id 从 1 开始。偏移量为 0 而将从 1 开始,因为您说跳过 0 行,同样,10 将从 11 开始,说跳过 10 行 实际上我没有使用从 1 开始的 id。我使用 id 作为 uuid。这是字母数字 是的,它仍然可以工作。

以上是关于TypeORM/NestJS 中的分页的主要内容,如果未能解决你的问题,请参考以下文章

无法使用 typeorm (NestJS) 在 SQL Server 中插入 bigint

未找到连接“默认”-TypeORM、NestJS 和外部 NPM 包

如何使用 typeorm nestjs 加入 3 个关系表

保存和检索日期时间到 mysql 日期时间,它使用 TypeOrm,NestJs | 存储前一天的日期节点

CodeIgniter 中的分页问题

iCarousel 中的分页