typescript 如何使用 typeorm 在 nestjs 中实现分页

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/53922503/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-21 05:44:53  来源:igfitidea点击:

How to implement pagination in nestjs with typeorm

typescriptnestjstypeorm

提问by HanJeaHwan

Anyway to get the total count and record with single query, instead of execute the query two times. Or how can i reuse the where condition in both query.

无论如何要通过单个查询获取总计数和记录,而不是执行查询两次。或者我如何在两个查询中重用 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
    }
}

{ count: 10, data: [ { id: 1, name: 'David' }, { id: 2, name: 'Alex' }] }

{ count: 10, data: [ { id: 1, name: 'David' }, { id: 2, name: 'Alex' }] }

回答by Ivan Vasiljevic

You can find some nice example in this project. In short typeormhas a really nice method specific to this usecase findAndCount.

你可以在这个项目中找到一些很好的例子。总之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
    }
}

Repository API you can find here. More documentation about Repositoryclass can be found here.

您可以在此处找到存储库 API 。更多关于Repository类的文档可以在这里找到。

回答by Gui Seek

summing up...

加起来...

This middleware checks if you have the take and skip parameters in the URL, if it does, it converts from string to number, if you don't use the default values. 10 for take and 0 for skip.

这个中间件检查 URL 中是否有 take 和 skip 参数,如果有,它会从字符串转换为数字,如果你不使用默认值。10 表示获取,0 表示跳过。

take is the number of results per page and skip, from where it should start reading records.

take 是每页和跳过的结果数,从哪里开始读取记录。

With that, I set up to intercept the "product / paged" route just for the GET method.

有了这个,我设置为只为 GET 方法拦截“产品/分页”路由。

With this I can retrieve these values in the controller and pass to TypeORM or an SQL query.

有了这个,我可以在控制器中检索这些值并传递给 TypeORM 或 SQL 查询。

Folders

文件夹

@Injectable()
export class PagerMiddleware implements NestMiddleware {
  use(req: any, res: any, next: () => void) {
    req.query.take = +req.query.take || 10;
    req.query.skip = +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 })
  }
}

Controller

控制器

@Controller('product')
export class TrainingDomainController {
  constructor(private service: YourService) {}

  @Get('paged')
  get(@Query() { take, skip }) {
    return this.service.findAll(take, skip);
  }
}

and service

和服务

@Injectable()
export class YourService {
  constructor(
    @InjectRepository(YourEntity)
    private readonly repo: MongoRepository<YourEntity>
  ) {}

  async findAll(take: number = 10, skip: number = 0) {
    const [data, total] = await this.repo.findAndCount({ take, skip });
    return { data, total };
  }
}

ok?

好的?

回答by sloan-dog

If you need to paginate through MANY records, i.e several iterations, (perhaps during a migration or mass update).

如果您需要对许多记录进行分页,即多次迭代(可能在迁移或大规模更新期间)。

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

}