1. 기본 세팅
한 페이지에 보여지는 게시글 수 = 10개
한 번에 보여지는 페이지 수 = 5개
+) 등록 최신순으로 조회
ex) 1 2 3 4 5 다음
이전 6 7 8 9 10 다음
이전 11 12
2. ROWNUM을 이용한 쿼리 작성
ROWNUM은 오라클에서 지원하는 가상 컬럼으로, 쿼리의 결과에 가상으로 1번부터 순번을 붙인다.
페이징 처리를 위해 게시글에 ROWNUM으로 순번을 매긴 후, 범위를 지정하여 해당 페이지에 보여줄 게시글만 가져올 수 있다.
SELECT BOARD_NUM
, BOARD_TITLE
, BOARD_WRITER
, TO_CHAR(REG_DATE, 'YYYY-MM-DD') AS REG_DATE
, READ_CNT
, ROWNUM
FROM SPRING_BOARD
WHERE ROWNUM >= 1 AND ROWNUM <= 10
ORDER BY BOARD_NUM DESC;
하지만 다음과 같이 조회했을 때 ROWNUM이 순서대로 붙지 않고 뒤죽박죽인 것을 볼 수 있는데, 이는 ROWNUM의 실행순서 때문이다.
** ROWNUM 실행 순서 : SELECT한 쿼리에 ROWNUM이 지정된 후 ORDER BY로 정렬된다.
SELECT BOARD_NUM
, BOARD_TITLE
, BOARD_WRITER
, REG_DATE
, READ_CNT
, ROWNUM ROW_NUM
FROM
(
SELECT BOARD_NUM
, BOARD_TITLE
, BOARD_WRITER
, TO_CHAR(REG_DATE, 'YYYY-MM-DD') AS REG_DATE
, READ_CNT
FROM SPRING_BOARD
ORDER BY BOARD_NUM DESC
)
WHERE ROWNUM >= 1 AND ROWNUM <= 10;
이럴 때는 ORDER BY로 정렬한 쿼리를 FROM절에 넣어 가져온 후에 SELECT로 다시 감싸 순번을 붙이면 된다.
+) FROM절에 서브쿼리를 삽입하여 새로운 테이블처럼 사용하는 것을 인라인 뷰라고 한다.
SELECT BOARD_NUM
, BOARD_TITLE
, BOARD_WRITER
, REG_DATE
, READ_CNT
, ROWNUM ROW_NUM
FROM
(
SELECT BOARD_NUM
, BOARD_TITLE
, BOARD_WRITER
, TO_CHAR(REG_DATE, 'YYYY-MM-DD') AS REG_DATE
, READ_CNT
FROM SPRING_BOARD
ORDER BY BOARD_NUM DESC
)
WHERE ROWNUM >= 11 AND ROWNUM <= 20;
하지만 ROWNUM을 11부터 조회했을 때 아무 데이터도 조회되지 않는데, ROWNUM은 임시 행번호이기 때문에 무조건 1부터 붙기 때문이다. 특정 행번호를 지정해 조회하고 싶다면 한 번 더 SELECT 절로 감싸 조회해야 한다.
SELECT BOARD_NUM
, BOARD_TITLE
, BOARD_WRITER
, REG_DATE
, READ_CNT
, ROW_NUM
FROM (
SELECT BOARD_NUM
, BOARD_TITLE
, BOARD_WRITER
, REG_DATE
, READ_CNT
, ROWNUM ROW_NUM
FROM (
SELECT BOARD_NUM
, BOARD_TITLE
, BOARD_WRITER
, TO_CHAR(REG_DATE, 'YYYY-MM-DD') AS REG_DATE
, READ_CNT
FROM SPRING_BOARD
ORDER BY BOARD_NUM DESC
)
)
WHERE ROW_NUM >= 11 AND ROW_NUM <= 20;
3. 쿼리가 완성되었으니, mapper 파일의 게시판 리스트 조회 select 태그로 삽입해준다.
<select id="getBoardList" resultMap="board">
SELECT (SELECT COUNT(BOARD_NUM) FROM SPRING_BOARD) - ROW_NUM + 1 AS ROW_NUMBER
, BOARD_NUM
, BOARD_TITLE
, BOARD_WRITER
, REG_DATE
, READ_CNT
, ROW_NUM
, REPLY_CNT
, IS_PRIVATE
FROM (
SELECT BOARD_NUM
, BOARD_TITLE
, BOARD_WRITER
, REG_DATE
, READ_CNT
, ROWNUM ROW_NUM
, REPLY_CNT
, IS_PRIVATE
FROM
(
SELECT BOARD_NUM
, BOARD_TITLE
, BOARD_WRITER
, TO_CHAR(REG_DATE, 'YYYY-MM-DD') AS REG_DATE
, READ_CNT
, (SELECT COUNT(REPLY_NUM)
FROM SPRING_REPLY
WHERE BOARD_NUM = SPRING_BOARD.BOARD_NUM) AS REPLY_CNT
, IS_PRIVATE
FROM SPRING_BOARD
ORDER BY BOARD_NUM DESC
)
)
WHERE ROW_NUM >= #{startNum} AND ROW_NUM <= #{endNum}
</select>
+) 게시글 번호 쿼리 추가 : 총 게시글 수 - 행번호 + 1
ex) 50번 글 번호를 구할 경우 : 최신순으로 조회되기 때문에 (54 53 52 51 50) 글 번호는 5번이 되어야 함.
-> 총 게시글 수 54개 - 50번 글 + 1 = 5번
(SELECT COUNT(BOARD_NUM) FROM SPRING_BOARD) - ROW_NUM + 1 AS ROW_NUMBER
+) xml 파일에서는 <,> 가 태그 기호로 인식되기 때문에 <, >로 표기해야 한다.
'TIL' 카테고리의 다른 글
| 230322 [jQuery, Ajax] (데이터 주고받기) (0) | 2023.03.22 |
|---|---|
| 230321 [Javascript] (댓글 수정 기능) (0) | 2023.03.21 |
| 230317 [Spring, thymeleaf] (layout) (0) | 2023.03.17 |
| 230314 [Spring] (Model / 의존성 주입) (0) | 2023.03.14 |
| 230313 [Spring, thymeleaf] (Controller / Mapping) (0) | 2023.03.13 |