Notice
Recent Posts
Recent Comments
Link
«   2025/05   »
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
Archives
Today
Total
관리 메뉴

사고쳤어요

[도서 쇼핑몰] Node.js - 도서 조회 페이지네이션 구현 본문

웹 풀스택

[도서 쇼핑몰] Node.js - 도서 조회 페이지네이션 구현

kevinmj12 2025. 3. 13. 23:20

게시판 사이트를 이용해보면 게시글이 페이지마다 일정하게 존재하고 1페이지, 2페이지, ... 로 되어 있는 것을 볼 수 있다.

만약 게시글이 최근 작성순으로 정렬되어있고 한 페이지에 게시글이 10개씩 존재한다면

1페이지에는 최근 1~10번째로 작성된 게시글, 2페이지에는 11~21번째로 작성된 게시글이 보여질 것이다.

즉, 페이지를 통해 게시글을 볼 때는 백엔드에서 모든 게시글을 보내줄 필요가 없이 10개씩만 보내주면 되는 것이다.

한 번에 다 보내는 것이 편하다고 할 수도 있지만, 게시글이 수만개인 상황에서 한 페이지만 조회할 때 낭비가 너무 심하다.

따라서 조회하는 페이지마다 해당 페이지에 해당하는 게시글들의 정보만을 보내주는 것이 현명할 것이다.

 

SELECT * FROM books LIMIT 5 OFFSET 0;

먼저 기본 베이스가 되는 SQL문은 다음과 같다.

LIMIT 5는 리턴하는 컬럼을 최대 5개로 제한하라는 뜻이고, OFFSET 0은 맨 위에서부터 0만큼 이동하라는 뜻이다.

SELECT * FROM books LIMIT 5 OFFSET 0;
SELECT * FROM books LIMIT 5 OFFSET 3;

 

위 두 사진을 비교해보면 OFFSET이 3일 때 id도 3만큼 이동하여 id가 4인 컬럼부터 5개가 보여진다.

페이지네이션 구현

LIMIT와 OFFSET은 프론트엔드에서 URL에 담아 보내줄 것이다.

따라서 해당 값들을 받아 LIMIT와 OFFSET값을 지정해 보내주도록 하자.

const books = (req, res) => {
  let categoryId = req.query.categoryid;
  let isNew = req.query.isnew;
  let { limit, page } = req.query;
  limit = parseInt(limit);
  page = parseInt(page);

  let sql = "SELECT * FROM books"; // 전체 도서 조회
  let values = [];
  if (categoryId && isNew) {
    // 카테고리별 신간 도서 조회
    sql = `SELECT * FROM books WHERE category_id = ? AND
      pub_date BETWEEN DATE_SUB(NOW(), INTERVAL 1 MONTH) AND NOW()`;
    values = [categoryId, isNew];
  } else if (categoryId) {
    // 카테고리별 조회
    sql = "SELECT * FROM books WHERE category_id = ?";
    values = [categoryId];
  } else if (isNew) {
    // 신간 조회
    sql = `SELECT * FROM books WHERE 
      pub_date BETWEEN DATE_SUB(NOW(), INTERVAL 1 MONTH) AND NOW()`;
    values = [isNew];
  }

  sql += `LIMIT ${limit} OFFSET ${(page - 1) * limit};`;

  conn.query(sql, values, (err, results) => {
    if (err) {
      return res.status(StatusCodes.BAD_REQUEST).json({
        msg: `Error: ${err.code}`,
      });
    }
    return res.status(StatusCodes.OK).json(results);
  });
};