자바(JAVA)/JSP 웹 프로그래밍 공부 (성낙현의 JSP 자바 웹 프로그래밍 참고)

JAVA/JSP 28. 회원제 게시판에 페이징 기능 추가 - 페이징이 필요한 이유, 페이징 구현 절차

개발학생 2025. 4. 15. 15:51
반응형

1. 페이징이 필요한 이유

*기존 회원제 게시판의 게시물이 1만 개가 되었다고 할 때의 문제점

⇒ 이래서 게시판에서는 게시글 목록을 보통 10~20개 정도씩 나눠 페이지별로 출력하는 것(=페이징)

(1) 스크롤이 길어져서, 사용자가 목록에서 원하는 게시글을 찾기 어려움(가독성 저하)

(2) 전송해야 할 데이터가 많아지므로, 페이지 로딩 속도가 느려짐

(3) 한 페이지에서 한꺼번에 많은 데이터를 처리해야 하므로, 데이터베이스에 과부하가 걸림

2. 페이징 구현 절차

1) 페이징 구현 이전 기본 설정값

(1) 한 페이지에 출력할 게시물의 개수 (레코드의 범위)

  • POSTS_PER_PAGE=10

(2) 한 화면(블록)에 출력할 페이지 번호의 개수

  • PAGES_PER_BLOCK=5

2) 페이징 구현 단계

(1) board 게시물에 저장된 전체 레코드 수 카운트

  • 계산 예: 전체 게시물을 105개라고 가정

(2) 각 페이지에서 출력할 게시물의 범위 계산

  • 계산식
    • 범위의 시작값: (현재 페이지 - 1) * POSTS_PER_PAGE + 1
    • 범위의 종료값: (현재 페이지 * POSTS_PER_PAGE)
  • 계산 예
    • 현재 1페이지일 때: 시작값 (1-1)10+1=1, 종료값 110=10
    • 현재 2페이지일 때: 시작값 (2-1)10+1=11, 종료값 210=20

(3) 전체 페이지 수 계산 - 계산된 결과는 무조건 올림 처리

 → 올림 처리를 안 하면 마지막 페이지의 게시물 5개 조회 불가
  • 계산식: Math.ceil(전체 게시물 수 / POSTS_PER_PAGE)
  • 계산 예: 게시물 수가 총 105개일 경우
    • 페이지 수: Math.ceil(105 / 10) = Math.ceil(10.5) = 11

(4) ‘이전 페이지 블록 바로가기’ 출력

  • 계산식: ((현재 페이지 - 1) / PAGES_PER_BLOCK) * PAGES_PER_BLOCK + 1
  • 계산 예 → pageTemp가 1일때는 이전 페이지 목록 바로가기를 출력하지 않음 → pageTemp가 1 이상일 때는 pageTemp - 1 페이지 블록 바로가기를 출력함
    • 현재 1페이지일 때: pageTemp = ((1-1) / 5) * 5 + 1 = 1
    • 현재 5페이지일 때: pageTemp = ((5-1) / 5) * 5 + 1 = 5

(5) 각 페이지 번호를 출력

  • 앞에서 계산한 pageTemp를 BLOCK_PAGE만큼 반복하면서 +1 연산 후 출력
  • 계산 예
    • pageTemp가 1일 때: “1 2 3 4 5”를 출력
    • pageTemp가 6일 때: “6 7 8 9 10”을 출력

(6) ‘다음 페이지 블록 바로가기’ 출력

  • 각 페이지 번호를 출력한 후, pageTemp + 1하여 다음 페이지 블록 바로가기 설정
  • → 마지막 페이지 번호가 5라면, 다음 페이지 블록은 6이 됨

페이징 구현 실습

더미 데이터 입력

  • 페이징 기능을 테스트하려면 데이터가 많이 입력되어 있어야 하므로, 반복문을 이용해서 더미 데이터 100개를 한 번에 삽입
    → 게시글을 하나씩 수동으로 채워 넣는 방법도 있지만, 다수의 데이터를 입력하려면 귀찮고 시간도 오래 걸리기 때문

WebContent → PagingBoard의 WriteProcess.jsp 파일을 열어 코드 수정

// WebContent/PagingBoard/WriteProcess.jsp

... 생략 ...

//DAO 객체를 통해 DB에 DTO 저장
BoardDAO dao = newBoardDAO(application);
//int iResult = dao.insertWrite(dto);  //원래 코드
//2.
int iResult = 0;
for (int i = 1; i <= 100; i++) {
  dto.setTitle(title + "-" + i);    //3.
  iResult = dao.insertWrite(dto);
}
dao.close();

... 생략 ...
  • Write.jsp 파일 실행 후 글을 작성한 결과

페이징용 쿼리문 작성

  • 사용하는 DBMS가 오라클이므로, rownum을 이용해서 쿼리문을 작성함

*rownum이란?

  • 오라클에서 생성된 모든 테이블에서 사용할 수 있는, 가상의 컬럼 → SELECT 쿼리문으로 추출하는 데이터(row)에 순차적으로 부여되는 순번(num)
  • 물리적으로 존재하는 컬럼이 아니므로, 값을 변경하기 위한 DML문(INSERT, UPDATE, DELETE)은 사용 불가

**실습

1. 명령 프롬프트(cmd) 실행

2. sqlplus 명령으로 오라클에 접속 (username: hello, pw:1234) → sql을 입력할 수 있는 상태가 됨

 

3. DESC 명령어로 member 테이블의 구조 확인 → 컬럼이 4개인 것을 확인할 수 있음

4. SELECT문으로 member 테이블의 모든 레코드 읽어오기

5. SELECT문에 id, pass 컬럼을 지정하고 rownum 사용 → rownum 컬럼을 만들지 않았음에도, rownum 컬럼에 순번이 출력됨

페이징 처리용 쿼리문 작성

  • 이전 28번 정리글의 ‘페이징 구현 절차’에서 게시물을 카운트하여 각 페이지에서 출력할 게시물의 범위를 계산했고, 그 결과에서 범위의 시작값과 끝값을 구함 → 이 시작값과 끝값을 이용해, CMD에 쿼리문 작성

첫 번째 페이지에 출력할 게시물

  • 총 10개의 게시물이 출력되는데, 화면이 너무 길어 두 번째 행부터는 생략 → 2페이지에 해당하는 행을 가져오고 싶다면, BETWEEN문의 값을 11~20까지로 변경
  • 매개변수를 이용해서 페이지별 목록의 범위를 계산하고, DAO에서 이를 적용한 쿼리문을 실행한 결과를 반환하면 됨
SELECT * FROM (    //3.(괄호 밖의 WHERE 절까지 포함)
  SELECT Tb.*, rownum rNum FROM (    //2.(괄호 밖의 'tb'까지 포함)
  SELECT * FROM board ORDER BY num DESC    //1.
  ) tb
)
WHERE rNum BETWEEN 1 and 10;
  1. board 테이블의 모든 게시물을 일련번호(num)에 대해 내림차순으로 정렬해서 가져옴
  2. 1번 쿼리문의 결과문을 *를 통해 모두 가져오고, rownum을 추가하여 순번 부여 → rownum 컬럼에는 별칭 rNum 사용
  3. 첫 페이지에 출력할 게시물 범위가 1~10이므로, rownum으로 부여한 번호를 이용해 구간을 정해 가져올 수 있음 → WHERE 절에서는 구간을 정하는 것이므로, BETWEEN 대신 rNum >=과 같이 조건을 부여할 수도 있음

반응형