본문 바로가기

JSP/기본다지기

[JSP] 페이징(Paging) ② [11월28일]

앞 포스팅에서

만든 Paging.java를 이용해서


실제로 페이징을 적용시켜보겠습니다..


우선은 앞서 만들어 둔 MemberDao.java의

selectAllMember() 메소드를 수정해야 합니다.


수정하기 전 원래 selectAllMember() 메소드의 경우에는


단순히 DB에 있는 모든 레코드의 정보를 가져오는 기능만

가지고 있었습니다.


이번 예제에서는

이 selectAllMember() 메소드에

DB에 있는 레코드의 모든 정보를 가져오는 기능에

그 레코드에 가상의 번호를 붙여서 총 몇 개의 레코드가

존재하는지를 계산하는 기능을 추가해야합니다.


페이징을 하기 위해서는

레코드의 총 갯수가 몇 개인지 

반드시 알아야 하기 때문입니다.


또한,

클라이언트가 특정 페이지를 요청했을 경우

그 페이지에 해당하는 내용만을 표시해주는 기능도

추가해주어야 합니다.


여기에서는 우선 클라이언트가 요청한 페이지의

내용만을 표시하는 메소드를 우선 구현해보고

레코드의 총 갯수를 계산하는 기능은

11월 30일 수업에서 알아보겠습니다.


우선 자바코드에 바로 들어가기 전에

SQL에 로그인하여 쿼리문을 입력하며 설명하겠습니다.



member 테이블

(여기에서는 편의상 member2 테이블을 새로 만들어 사용하였습니다.)


member테이블을 전체 조회 할 경우

위 그림처럼 351개의 결과가 있다고 마지막에 표시되며,

모든 결과값이 표시됩니다.


이것이 기존에 만들어 둔 selectAllMember() 메소드의 기능입니다.


이번에는 여기에 ROWNUM 이라고 하는

가상의 번호를 붙여주는 컬럼을 추가하여 조회해야 합니다.



(여기서는 편의상 모든 컬럼을 조회하지 않고

ROWNUM 컬럼과 NUM 컬럼만 조회하겠습니다.)



우선 결과를 보면, ROW_NUM이라는 이름의 새로운 컬럼과,

원래 우리가 넣어둔 값인 NUM값이

마치 JOIN한 것 처럼 조회된 것을 볼 수 있습니다.


ROWNUM은 1번 부터 시작하여

위에서부터 번호를 매겨줄 수 있는 기능입니다.


굳이 NUM으로 해도 될 것을 왜 ROWNUM을 써?

라고 의문을 가지실 지 모르겠습니다만


앞선 실습에서 이미 생성된 회원을

삭제하는 과정에서 

중간에 번호가 떠버리는 현상을 보셨다면

왜 NUM을 사용할 수 없는지 이해가 되실 것입니다.


1번 2번 5번 회원이 있다고 치면,

실제 회원은 3명이지만, 번호는 5번까지 나오는 것이

NUM을 사용할 수 없는 가장 큰 이유입니다.


SELECT ROWNUM as row_num, num FROM member2;


위에 파란줄 친 부분을 부가설명하면,

'ROWNUM을 row_num이라는 컬럼이름으로 출력하겠다.'

라는 뜻입니다.


그래서 이걸 가지고 뭐 어떻게 페이징을 하느냐..


차근차근 살펴보겠습니다.


우선 검색 결과를 먼저 보시죠.


앞선 전체 조회에서는 351개의 결과가 있었지만,

위 쿼리문에서는 10개의 결과만 출력하고 있습니다.

우리가 페이지에 10개씩 출력하고 싶은 것과 딱 맞아 떨어지죠?


서브쿼리에 대한 이해가 조금 필요한 쿼리문이니

기억이 나지 않으면 구글링을 합시다!


위 쿼리문을 해석해보면 이렇습니다


1행 : SELECT * 

(모든 컬럼(*)을 전부 조회하겠다.)


2~3행 : FROM (SELECT ROWNUM as row_num, member2.* FROM member2)

( (괄호) 안에 있는결과 값 중에서 )


4행 : WHERE row_num <= 10

(위 쿼리문을 통해 나온 결과값 중에서

row_num이 10 이하인 값만 출력하겠다.)



괄호 안에 있는 쿼리문은

위에서 살펴본 row_num과 num만 출력된 쿼리문에서

num 이외에 member의 모든 컬럼을 조회하도록 바꾼 것 뿐입니다.



그러면 여기서 11번과 20번을 한번 출력해볼까요?



참 쉽죠?


하지만, 여기에는 약간의 문제가 있다고 합니다.


우리 예제처럼 350개정도의 레코드라면 문제가 없지만 


수억개 수십억개의 레코드라면, 모든 레코드를 다 조회한 뒤


그 중의 10개만 추려내는 방식으로 작동하는 탓에


성능상의 문제를 야기할 가능성이 있기 때문입니다.



그래서 실무에서는 아래와 같은 쿼리문으로 바꾸어(Tuning하여) 사용한다고 합니다.



결과는 동일하지만

위에서 사용한 쿼리문을 또다시 서브쿼리로 만들어서

쿼리 안에 서브쿼리에 서브쿼리를 쓴 형태입니다.


이렇게 쿼리문을 작성하게 되면

아무리 레코드 갯수가 많아도

원하는 갯수만큼만 조회하기 때문에

DB에 걸리는 부하를 최소화 할 수 있다고 합니다.


이제 페이징을 위한 쿼리문이 완성되었습니다.


위 쿼리문에서 11 부분이 바로 beginPage

20 부분이 endPage라는 것은 이미 감이 오셨으리라 생각합니다.


그러면 다음 포스팅에서는

이 쿼리문을 이용하여

진짜 진짜 진짜

페이징을 해보도록 하겠습니다.