如何使用Typeorm在NestJS中实现分页

时间:2018-12-25 12:43:34

标签: typescript nestjs typeorm

无论如何,只需一次查询即可获取总数并进行记录,而不必两次执行查询。或者如何在两个查询中重用where条件。

async findAll(query): Promise<Paginate> {
    const take = query.take || 10
    const skip = query.skip || 0
    const keyword = query.keyword || ''

    const builder = this.userRepository.createQueryBuilder("user")
    const total = await builder.where("user.name like :name", { name: '%' + keyword + '%' }).getCount()
    const data = await builder.where("user.name like :name", { name: '%' + keyword + '%' }).orderBy('name', 'DESC').skip(skip).take(take).getMany();

    return {
        data: data,
        count: total
    }
}

{     数:10,     数据:[     {         编号:1         名称:“ David”     },     {         编号:2         名称:“ Alex”     }] }

5 个答案:

答案 0 :(得分:6)

您可以在此project中找到一些不错的示例。简而言之,typeorm有一个特定于此用例findAndCount的非常好的方法。

async findAll(query): Promise<Paginate> {
    const take = query.take || 10
    const skip = query.skip || 0
    const keyword = query.keyword || ''

    const [result, total] = await this.userRepository.findAndCount(
        {
            where: { name: Like('%' + keyword + '%') }, order: { name: "DESC" },
            take: take,
            skip: skip
        }
    );

    return {
        data: result,
        count: total
    }
}

存储库API,您可以找到here。可以在here中找到有关Repository类的更多文档。

答案 1 :(得分:2)

您还可以查看此NestJS和TypeORM软件包:

https://github.com/nestjsx/nestjs-typeorm-paginate

答案 2 :(得分:1)

import { Injectable, NestMiddleware } from '@nestjs/common';

@Injectable()
export class PagerMiddleware implements NestMiddleware {
  use(req: any, res: any, next: () => void) {
    req.query.take = Number(req.query.take) || 10
    req.query.skip = Number(req.query.skip) || 0
    next();
  }
}

# ... and apply in module.

export class AdminFeatureApi implements NestModule {
  configure(consumer: MiddlewareConsumer) {
    consumer.apply(PagerMiddleware)
    .forRoutes({ path: 'product/paged', method: RequestMethod.GET })
  }
}

答案 3 :(得分:1)

我更喜欢使用 page 而不是直接跳过

  • 端点示例:/users?page=4&take=3

    async findAll(query): Promise<Paginate> {
        const take = query.take || 10
        const page=query.page || 1;
        const skip= (page-1) * take ;
        const keyword = query.keyword || ''
    
        const [result, total] = await this.userRepository.findAndCount(
            {
                where: { name: Like('%' + keyword + '%') }, order: { name: "DESC" },
                take: take,
                skip: skip
            }
        );
    
        return {
            data: result,
            count: total
        }
    }
    

    2/.更好的方法(处理响应):

     async findAll(query): Promise<Paginate> {
         const take = query.take || 10
         const page=query.page || 1;
         const skip= (page-1) * take ;
         const keyword = query.keyword || ''
    
         const data = await this.userRepository.findAndCount(
             {
                 where: { name: Like('%' + keyword + '%') }, order: { name: "DESC" },
                 take: take,
                 skip: skip
             }
         );
         return paginateResponse(data ,page,limit)
    
     }
    
    export function paginateResponse(data,page,limit) {
      const [result, total]=data;
      const lastPage=Math.ceil(total/limit);
      const nextPage=page+1 >lastPage ? null :page+1;
      const prevPage=page-1 < 1 ? null :page-1;
      return {
        statusCode: 'success',
        data: [...result],
        count: total,
        currentPage: page,
        nextPage: nextPage,
        prevPage: prevPage,
        lastPage: lastPage,
      }
    }
    

答案 4 :(得分:0)

如果您需要对许多记录进行分页,即多次迭代(也许在迁移或批量更新期间)。

async getPaginatedResults(query: any, transactionManager?: EntityManager): Promise<any> {

}