오늘은 서버에서 페이지네이션을 하는 방법을 써보도록 할 것이다.
PagingManager라는 class를 만들어서 관리해보도록 하자.
아래와 같은 4개의 파라미터를 받아 페이지네이션을 실행시킬 것이다.
totalRowCount: 전체 행 수
size: 페이지 크기 (한 페이지에 표시되는 항목 수)
page: 현재 페이지 번호
query: TypeORM의SelectQueryBuilder<T>
인스턴스
import { SelectQueryBuilder } from 'typeorm';
export class PagingManager<T> {
private readonly totalPage: number;
private readonly currentPage: number;
constructor(
private readonly totalRowCount: number,
private readonly size: number,
private readonly page: number,
private readonly query: SelectQueryBuilder<T>,
) {}
}
this.totalPage = Math.ceil(this.totalRowCount / this.size) || 1;
this.currentPage =
this.page < 1
? 1 // 페이지가 1보다 작으면 1로 설정
: this.page > this.totalPage
? this.totalPage // 페이지가 전체 페이지 수를 초과하면 마지막 페이지로 설정
: this.page; // 그 외의 경우에는 주어진 페이지 번호로 설정
pagedQuery()
함수를 만든다.₩ get pagedQuery() {
return this.query.take(this.size).skip(this.size * (this.currentPage - 1));
}
paging()
함수를 만들어 준다. get paging() {
return {
prevPage: this.currentPage <= 1 ? 1 : this.currentPage - 1,
currentPage: this.currentPage,
nextPage:
this.currentPage >= this.totalPage
? this.totalPage
: this.currentPage + 1,
totalPage: this.totalPage,
};
}
import { SelectQueryBuilder } from 'typeorm';
export class PagingManager<T> {
private readonly totalPage: number;
private readonly currentPage: number;
constructor(
private readonly totalRowCount: number,
private readonly size: number,
private readonly page: number,
private readonly query: SelectQueryBuilder<T>,
) {
this.totalPage = Math.ceil(this.totalRowCount / this.size) || 1;
this.currentPage =
this.page < 1
? 1
: this.page > this.totalPage
? this.totalPage
: this.page;
}
get pagedQuery() {
return this.query.take(this.size).skip(this.size * (this.currentPage - 1));
}
get paging() {
return {
prevPage: this.currentPage <= 1 ? 1 : this.currentPage - 1,
currentPage: this.currentPage,
nextPage:
this.currentPage >= this.totalPage
? this.totalPage
: this.currentPage + 1,
totalPage: this.totalPage,
};
}
}
async getProducts(
queryParams: GetProductsAdminRequestDto,
): Promise<GetProductsAdminResponseDto> {
const countQuery = await this.productsRepository.getFilteredCountQuery(
queryParams,
);
const query = await this.productsRepository.getFilteredQuery(queryParams);
const { page, size } = queryParams;
const pagingManager = new PagingManager(
await countQuery.getCount(),
size,
page,
query,
);
return {
paging: pagingManager.paging,
products: await pagingManager.pagedQuery.getMany(),
};
}