이전에 만든 CRUD 게시판은 100개의 게시글이 있다면 한번에 100개의 게시글이 모두 보여진다. 정말 비효율적인 게시판이다..(ㅎ) 그래서 게시판 목록 페이징 처리를 하려고 한다. 그러면 좀 더 게시판 스럽지 않을까 싶다! 나는 만들어 놓은 CURD 게시판을 수정해서 작업을 하는 것이기 때문에 본인의 게시판에 맞게 적절히 섞어(?)주면 된다. 1. 페이징 규칙 먼저 페이징이 어떤식으로 처리되는 지 이해해보자. 페이지당 게시글을 10개씩 보여주고 페이징 버튼은 최대 10개까지만 보인다고 하자.
[1] [2] [3] [4] [5] [6] [7] [8] 총 게시글 수가 77이면 페이지 번호의 끝 번호가 8이여야 한다. 페이지의 끝 번호를 알기 위해서는 총 게시글의 수가 필요하다.
[1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [다음] [이전] [11] [12] [13] 화면에 보여줄 페이지 버튼의 수가 10개 이상이라면 다음 버튼을 이용해 다음 페이지를 이용할 수 있어야 한다. 시작 페이지의 번호가 1이 아니라면 이전 버튼을 이용해 이전 페이지를 이용할 수 있어야 한다.
[1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [다음] [이전] [11] [12] [13] [14] [15] [16] [17] [18] [19] [20] [다음] [21] [22] 현재 페이지의 번호가 1~10 사이라면 시작 번호는 1이여야 한다. 현재 페이지의 번호가 11~20 사이라면 시작 번호는 11이여야 한다. 2. 페이징 원칙 페이징 처리를 함에 있어서 원칙들이 있다.
3. SQL : LIMIT 페이징 처리를 확인하기 위해서 DB에 100개의 데이터를 넣어뒀다. 그럼 게시판 목록을 조회하는 쿼리를 실행하게 되면 어떻게 될까?
100개의 게시글이 한번에 나올 것이다. 한 페이지(화면)에 100개 혹은 1000개의 게시글을 한번에 보여주기엔 벅차다. 그렇기에 게시글 목록에는 페이징 처리가 반드시 필요하다. DB에 따라 페이징 처리를 할 수 있는 쿼리가 존재한다고 한다. 그렇기에 각자 사용하는 DB를 확인해서 쿼리를 사용하면 된다. 나는 MySQL을 사용하기 때문에 LIMIT을 이용해서 페이징 처리를 할 것이다.
LIMIT을 위와 같이 사용하게 되면 특정 페이지의 게시글을 보여줄 수 있다. 게시글 번호로 내림차순 정렬한 데이터를 출력할 행부터 출력할 갯수까지 조회해주는 쿼리이다. 데이터의 행은 0부터 시작한다. 따라서 LIMIT 0, 10 이라고 설정하면 0행부터 10개까지의 게시글이 조회될 것이다. 그러면 페이징 처리를 하기 위해선 어떻게 조회를 해야 할까? 1페이지 -> 00행 ~ 09행 (10개) : LIMIT 0, 10 2페이지 -> 10행 ~ 19행 (10개) : LIMIT 10, 10 3페이지 -> 20행 ~ 29행 (10개) : LIMIT 20, 10 이런식으로 페이징 처리가 이루어져야 한다. 그래서 특정 페이지의 첫번째 게시글의 행번호와 출력할 갯수만 전달 받는다면 특정 페이지의 게시글들을 조호할 수 있을 것이다. 나는 전달받을 파라미터들을 각각 pageStart와 perPageNum으로 정했다. 그러면 아래와 같은 쿼리로 페이징 처리를 하면 된다.
특정 페이지를 조회하기 위해 두 개의 파라미터를 담는 클래스를 만들 것이다. 이렇게 클래스를 만드는 이유는 뭘까? 게시판에도 여러 종류의 게시판이 존재한다. 그러면 게시판 마다 페이징 조회 로직을 생성해야 한다. 하지만 페이징 관련된 기능들을 별도의 클래스로 분리해놓는다면 조금 더 효율적인 작업을 할 수 있다. 4. 특정 페이지 조회를 위한 Criteria 클래스 게시글 조회 쿼리에 전달될 파라미터를 담게 될 클래스이다. VO라고 생각하면 쉬울 것이다. Criteria
최초로 게시판 목록에 들어 왔을 때를 위해서 기본 셋팅을 해야 한다. 왜냐하면 페이징을 처리하기 위해선 현재 페이지 번호와 페이지당 게시글 수가 필요한데 처음 게시판에 들어오게 되면 두 개의 정보를 가져올 방법이 없기 때문에 기본 생성자를 통해 기본 값을 셋팅하도록 하자. 현재 페이지를 1페이지로, 페이지당 보여줄 게시글의 수를 10개로 기본 셋팅해두었다.
- setPage() : 페이지가 음수값이 되지 않게 설정. 음수가 되면 1페이지를 나타낸다. - setPerPageNum() : 페이지당 보여줄 게시글 수가 변하지 않게 설정했다.
5. 게시판 페이징을 처리하는 PageMaker 클래스 페이징에 관련된 버튼들을 만드는 기능을 하는 클래스이다. 페이지에 페이징 버튼들을 만들기 위한 계산 클래스라고 생각하면 된다. 그래서 계산이 필요한 부분이 많다.(ㅠㅠ) 하지만 그냥 공식이라 생각하고 이렇게 쓰는구나, 정도의 이해만 하고 넘어가도 된다. PageMaker
- 22행: 총 게시글 수를 셋팅할때 calcData() 메서드를 호출하여 페이징 관련 버튼 계산을 한다. - 25행: 페이징의 버튼들을 생성하는 계산식을 만들었다. 끝 페이지 번호, 시작 페이지 번호, 이전, 다음 버튼들을 구한다.
조회 쿼리에서 count(*)를 이용해서 구해야 한다. 총 게시글 수 쿼리는 조금 있다가 설정할 것이다.
끝 페이지 번호는 총 게시글 수와 연관이 있다. 근데 100개의 게시글을 20개씩 보여준다고 하면 끝 페이지의 번호가 5여야 하는데 위의 계산식으로 계산을 하게 되면 끝 페이지 번호가 20이 나오게 된다. ( Math.ceil(1/20)*20 = 20 ) 그래서 총 게시글 수와 페이지당 보여줄 게시글의 갯수로 마지막 페이지 번호를 구해 서로 비교해서 화면에 보여질 끝 페이지 번호를 구해야 한다.
마지막 페이지의 번호를 구한 뒤, 끝 페이지 번호보다 작은 경우에 마지막 페이지의 번호를 끝 페이지 번호로 저장해준다. 화면에 보여질 끝 페이지 번호는 마지막 페이지의 번호보다 클 수는 없다. 그렇기 때문에 위와 같은 조건을 넣어줘야 한다. 이 부분은 시작 페이지 번호까지 구한 뒤에 처리해줘야 한다.
시작 페이지 번호를 구할 때, 마지막 페이지 번호가 화면에 보여질 페이징 버튼의 갯수보다 작으면 문제가 생긴다. 시작 페이지 번호가 음수가 되어버리는 상황이 발생한다. 예를들면 끝 페이지의 번호가 3이고, 보여줄 페이지 갯수가 5라면, 시작 페이지 번호는 -1이 된다. 따라서, 구한 시작페이지 번호가 0보다 작으면(음수) 시작 페이지를 1로 해주는 로직을 추가해야 한다.
이전 버튼은 시작 페이지 번호가 1이 아니면 생기면 된다.
보여지는 버튼의 수를 정하면 된다. 나는 5개만 보이게 할 것이다. PageMaker 객체를 사용하려면 setCri() 와 setTotalCount()를 먼저 호출해서 값을 셋팅해야 한다. 페이징 버튼들의 값을 구하려면 제일 먼저 총 게시글 수가 있어야 위의 계산식대로 차례로 구할 수 있다. 그렇기에 총 게시글을 셋팅할 때 계산식 메소드를 호출하게 한 것이다. 또한 Criteria 객체에서 필요한 page 와 perPageNum을 사용하기 위해서 setCri()를 먼저 셋팅해야 한다. 컨트롤러에서 객체로 값을 셋팅할 때 유의하자. 6. 목록 조회 수정 ** 이전에 만들어 둔 CURD 게시판을 수정해서 사용한다. 6-1. Controller
- 02행: 현재 페이지 번호와 페이지당 보여줄 게시글 수가 담긴 Criteria 객체를 사용한다. - 06행: PageMaker() 객체를 생성한다. - 07행: page와 perPageNum을 셋팅해준다. - 08행: 총 게시글의 수를 셋팅해준다. 아직 총 게시글 수를 조회하는 로직은 구현하지 않았기 때문에 현재 DB에 있는 총 게시글의 수인 100을 넣어줬다. - 10행: 원래의 목록 조회 로직에서 Criteria 파라미터를 사용하기 위해 수정했다. - 12행: 셋팅된 pageMaker에는 페이징을 위한 버튼의 값들이 들어있고 ModelAndView를 이용해 jsp에 넘겨준다. 6-2. Service 영역 및 DAO
게시글 목록 조회하는 Service, DAO 영역에 Criteria 객체에 담긴 파라마터를 보내기 위해 수정했다. 각자의 목록 조회에 맞게 수정하면 된다. Criteria 객체에 담아서 SQL 매핑에 보낼 파라미터는 특정 페이지 게시글의 행(pageStart)과 페이지당 보여줄 게시글의 갯수(perPageNum)이다. 6-3. SQL
- 10행: 페이징 조회를 위해 LIMIT를 이용해서 원래의 목록 조회 쿼리를 수정했다. 6-4. JSP
- 02행: 이전 버튼의 생성 여부를 확인하여 버튼을 보여줄 것이다. - 06행: 현재 페이지가 어디인 지 알기 위해 추가했다. - 07행: 페이지의 시작 번호와 끝 번호를 이용해 페이지 버튼들을 뿌려줄 것이다. - 12행: 다음 버튼의 생성 여부를 확인하여 버튼을 보여줄 것이다. 7. 총 게시글 갯수 구하기 (totalCount) 그럼 마지막으로 총 게시글 갯수를 구하는 로직을 만들자. 7-1. SQL
- 01행: 결과는 int로 리턴되어야 한다. - 04행: 조회한 결과의 갯수를 뿌려주는 쿼리이다. - 08행: 총 게시글 중에 삭제된 건 빼야 한다. 7-2. DAO 7-3. Service 영역
7-4. Controller
100으로 셋팅한 부분에 총 게시글 수를 구하는 로직을 넣었다. 8. 확인 밑에 페이징 버튼들이 나오고 10개의 게시글만 나왔다! 그럼 다른 페이지의 버튼를 눌러보자. 페이지에 따라 목록이 바뀐다. 이전, 다음 버튼도 알맞게 구동된다! 페이징 처리에 성공했지만 아직 개선해야 될 부분이 남아있다. 페이징 원칙에서도 언급했는데, 특정 페이지의 한 게시글을 조회, 수정, 삭제를 하고 난 후에 다시 목록으로 돌아가게 될 경우 그 특정 페이지로 돌아가야 한다. 그 부분만 해결된다면 페이징 처리는 완성된것이다. |