04. 게시물 목록 불러오기 및 페이징 처리

04. 게시물 목록 불러오기 및 페이징 처리

1. 게시물 목록불러오기

Criteria.java

- 게시물의 페이징 처리와 검색에 필요한 파라미터를 하나의 객체로 묶어서 전달할 수 있다.

package me.light.domain; // 생략 ... @Setter @Getter @ToString public class Criteria { private int pageNum; // 게시물이 속한 페이지 번호 private int amount; // 게시물 수 private String category; private String type; // 검색타입 private String keyword; // 검색어 public Criteria() { this(1,10); } public Criteria(int pageNum, int amount) { super(); this.pageNum = pageNum; this.amount = amount; } public String[] getTypeArr() { return type == null ? new String[] {} : type.split(""); } }

BoardController.java

@GetMapping("/list") public void list(Model model,Criteria cri, String category) { cri.setCategory(category); model.addAttribute("list",service.getList(cri)); model.addAttribute("pageMaker", new PageDTO(cri, service.getTotal(cri))); }

- category 파라미터는 요청한 게시판의 종류를 의미한다.

- http://localhost:8080/board/list?category=news로 요청하였다면 뉴스 카테고리 게시판으로 이동할 것이다.

- PageDTO객체는 페이징 처리를 위한 객체이다.

- BoardService객체의 getList()를 호출하여 모델객체에 담아 list.jsp 객체로 이동한다.

BoardServiceImpl.java

@Override public List getList( Criteria cri) { return mapper.getList(cri); }

- BoardServiceImpl에서는 다시 BoardMapper객체의 getList()를 호출한다.

BoardMapper.java

public interface BoardMapper { List getList(Criteria cri); }

- BoardMapper객체는 BoardMapper.xml에서 이에 대응하는 태그를 찾는다.

BoardMapper.xml

select * from ( select rownum rn, bno, title, content, writer, regdate, updatedate, category, catename, replycnt from ( select /*+ INDEX_DESC(tbl_board pk_board) */ bno, title, content, writer, regdate, updatedate, category, catename, replycnt from tbl_board where category= #{category} and bno>0 ) where rownum <= #{pageNum} * #{amount} ) where rn > (#{pageNum} - 1) * #{amount}

list.jsp

[${board.title}] ${board.writer} ${board.content}

- list라는 이름으로 Model객체에 게시물 목록을 화면에 출력한다.

게시물의 목록을 불러온다.

2. 페이징 처리

package me.light.domain; // 생략... @Getter @Setter public class PageDTO { private int startPage; private int endPage; private boolean prev; private boolean next; private int total; private Criteria cri; public PageDTO(Criteria cri, int total) { this.cri = cri; this.total = total; this.endPage = (int) (Math.ceil(cri.getPageNum() /10.0)) * 10; this.startPage = this.endPage - 9; int realEnd = (int) (Math.ceil( (total*1.0) / cri.getAmount())); if(realEnd < this.endPage) { this.endPage = realEnd; } this.prev = this.startPage > 1; this.next = this.endPage < realEnd; } }

정의된 필드 변수의 역할은 다음과 같다.

startePage : 페이지상 표시되는 첫번째 번호이다.

endPage : 페이상 표시되는 마지막 번호이다.

prev : 이전 페이지이다. 첫 페이지에서는 보이지 않는다.

next : 다음 페이지이다. 마지막 페이지에서는 보이지 않는다.

total : 게시물의 총 갯수다. 컨트롤러에서 service.getTotal(cri) 호출하여 이 값을 받아 온다.

startPage와 endPage의 계산

- 첫번째 페이지 계산

endPage = (int) (Math.ceil(페이지 번호 /페이지 수 )) * 페이지 수 ;

한페이지에 보여줄 페이지 수를 10개라고 하고 21페이지 ~ 30페이지의 endPage를 위와 같이 계산하면

Math.ceil(21/10) * 10 = 30이 된다. 따라서 21페이지에서 30페이지의 마지막 페이지 번호는 30이다.

- 현재 페이지에 보이는 마지막 페이지 계산

this.startPage = this.endPage - 9;

한 페이지에 보여줄 페이지 수가 10개 이므로 첫 번째 페이지수는 9를 뺀값이 된다.

따라서 startPage는 21페이지가 된다.

- 실제 마지막 페이지

게수물의 총 개수를 234개라고 하고 10개의 게시물을 페이징 처리한다고 하자

총 페이지수는 24개이며 실제 마지막페이지는 24페이지가 되어야 한다.

그런데 endPage 계산법에 의하면 마지막페이지가 30이된다. 이를 바로잡을 필요가 있다.

int realEnd = (int) (Math.ceil( (total*1.0) / cri.getAmount())); if(realEnd < this.endPage) { this.endPage = realEnd; }

실제 마지막 페이지는 항상 24이며 10~20페이지 의 사이의 endPage는 20이된다.

따라서 20~30 페이지 구간이 아닌 곳에서는 항상 realEnd 값이 크다.

따라서 endPage가 realEnd보다 큰 구간에서면 endPage의 값을 realEnd로 바꾸면 된다

- 이전페이지와 다음 페이지

this.prev = this.startPage > 1; this.next = this.endPage < realEnd;

1~10페이지 구간은 startPage 값이 1이다.

나머지 구간은 starPage가 항상 1보다 큰 값을 가진다.

이 사실을 이용하면 startPage > 1 인 구간에서면 startPage값을 true로 값으로 한다.

화면에서의 페이징 처리

처음으로 이전 ${num} 다음

컨트롤러에서 페이징 처리에 관한 정보를 pageMaker라는 이름으로 모델객체에 담아 보냈다.

jstl문법을 사용하여 pageDTO 객체를 사용했다.

model.addAttribute("pageMaker", new PageDTO(cri, service.getTotal(cri)));

- 페이지 번호 화면에 표시

c:foreach 반복문을 사용하여 페이지 번호를 출력하는 코드이다.

${num}

- 다음페이지와 이전 페이지

이전 다음

이전버튼과 다음 버튼

1~10페이지를 제외하고 나머지 페이지에서는 이전페이지 버튼이 나타난다.

첫 페이지에서는 이전 버튼이 보이지 않는다.

마지막 페이지 구간을 제외하고 모든 곳에서 다음페이지 버튼이 나타난다.

마지막 페이지에서는 다음 버튼이 보이지 않는다.

from http://k-develpoper.tistory.com/332 by ccl(A) rewrite - 2021-09-06 14:26:53