skip
和 take
是 TypeORM 提供的用于分页查询的方法。下面是对这两个方法的详细解释:
1. skip
- 作用:
skip
方法用于跳过指定数量的记录。 - 参数:接受一个整数值,表示要跳过的记录数。
- 用途:通常用于分页查询中,跳过前面的页数,以便获取当前页的数据。
2. take
- 作用:
take
方法用于限制返回的记录数量。 - 参数:接受一个整数值,表示要返回的最大记录数。
- 用途:通常用于分页查询中,限制每页返回的记录数。
示例
假设你有一个包含 100 条记录的 Article
表,并且你想实现每页 10 条记录的分页查询。
分页逻辑
- 第一页:跳过 0 条记录,取前 10 条记录。
- 第二页:跳过 10 条记录,取接下来的 10 条记录。
- 第三页:跳过 20 条记录,取接下来的 10 条记录。
计算公式
skip
= (页码 - 1) * 每页记录数take
= 每页记录数
示例代码
以下是如何在 ArticleService
中使用 skip
和 take
方法实现分页查询的示例:
import { Injectable } from '@nestjs/common';
import { CreateArticleDto } from './dto/create-article.dto';
import { UpdateArticleDto } from './dto/update-article.dto';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { ArticleEntity } from '../user/entities/article.entity';
@Injectable()
export class ArticleService {
constructor(
@InjectRepository(ArticleEntity)
private readonly articleRepository: Repository<ArticleEntity>,
) {}
create(createArticleDto: CreateArticleDto) {
return this.articleRepository.save(createArticleDto);
}
async findAll(page: number = 1, limit: number = 10) {
const skip = (page - 1) * limit;
const [articles, total] = await this.articleRepository.findAndCount({
skip,
take: limit,
});
return {
articles,
total,
page,
limit,
totalPages: Math.ceil(total / limit),
};
}
findOne(id: number) {
return this.articleRepository.findOneBy({ id });
}
update(id: number, updateArticleDto: UpdateArticleDto) {
return this.articleRepository.update(id, updateArticleDto);
}
remove(id: number) {
return this.articleRepository.delete(id);
}
}
解释
skip
:(page - 1) * limit
计算出需要跳过的记录数。take
:limit
指定每页返回的记录数。findAndCount
:返回一个包含两个元素的数组,第一个元素是查询结果数组,第二个元素是总记录数。articles
: 当前页的记录列表。total
: 总记录数。page
: 当前页码。limit
: 每页的记录数。totalPages
: 总页数,通过Math.ceil(total / limit)
计算得出。
控制器示例
在控制器中,你需要接收分页参数并传递给服务层:
import { Controller, Get, Post, Body, Param, Query } from '@nestjs/common';
import { ArticleService } from './article.service';
import { CreateArticleDto } from './dto/create-article.dto';
import { UpdateArticleDto } from './dto/update-article.dto';
@Controller('articles')
export class ArticleController {
constructor(private readonly articleService: ArticleService) {}
@Post()
create(@Body() createArticleDto: CreateArticleDto) {
return this.articleService.create(createArticleDto);
}
@Get()
findAll(@Query('page') page: number = 1, @Query('limit') limit: number = 10) {
return this.articleService.findAll(page, limit);
}
@Get(':id')
findOne(@Param('id') id: string) {
return this.articleService.findOne(+id);
}
@Patch(':id')
update(@Param('id') id: string, @Body() updateArticleDto: UpdateArticleDto) {
return this.articleService.update(+id, updateArticleDto);
}
@Delete(':id')
remove(@Param('id') id: string) {
return this.articleService.remove(+id);
}
}
测试
你可以通过发送 HTTP 请求来测试分页功能。例如,使用 curl
或 Postman 发送 GET 请求:
curl "http://localhost:3000/articles?page=1&limit=10"
这将返回第一页的 10 条记录以及分页元数据。
总结
skip
:跳过指定数量的记录。take
:限制返回的记录数量。findAndCount
:返回查询结果和总记录数,便于计算分页元数据。
通过这些方法,你可以在 NestJS 中轻松实现高效的分页查询。