[spring] MyBatis와 스프링에서 페이징 처리
업데이트:
MyBatis는 SQL을 그대로 사용할 수 있기 때문에 인라인뷰를 이용하는 SQL을 작성하고, 필요한 파라미터를 지정하는 방식으로 페이징 처리를 하게 된다. 필요한 파라미터는 다음과 같다.
- 페이지 번호(pageNum)
- 한 페이지당 몇 개의 데이터(amount)
이 데이터들을 하나의 객체로 묶어서 전달하는 방식이 나중을 생각하면 좀 더 확장성이 좋다.
- Criteria 클래스 생성
// Criteria.java
package org.zerock.domain;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
@Getter
@Setter
@ToString
public class Criteria {
private int pageNum;
private int amount;
public Criteria() {
this(1, 10);
}
public Criteria(int pageNum, int amount) {
this.pageNum = pageNum;
this.amount = amount;
}
}
생성자를 통해 기본값을 1페이지, 10개로 지정해서 처리한다.
MyBatis 처리와 테스트
- src/main/java/../BoardMapper 추가
public List<BoardVO> getListWithPageing(Criteria cri);
- src/main/resources/../BoardMapper.xml 추가
<!-- paging -->
<select id="getListWithPaging"
resultType="org.zerock.domain.BoardVO">
<![CDATA[
select
bno, title, content, writer, regdate, updatedate
from(
select /*+ INDEX_DESC(tbl_board pk_board)*/
rownum rn, bno, title, content, writer, regdate, updatedate
from
tbl_board
where rownum <= 20
)
where rn > 10
]]>
</select>
페이징 테스트와 수정
XML 설정이 제대로 동작하는지 테스트를 먼저 진행하는 것이 좋다. src/test/java 내 BoardMapperTests 클래스에 메서드를 추가한다.
@Test
public void testPaging() {
Criteria cir = new Criteria();
List<BoardVO> list = mapper.getListWithPaging(cri);
list.forEach(board -> log.info(board));
}
SQL에 문제가 없다는 것을 확인했다면 이제 Criteria 객체 내부의 값을 이용해 SQL이 동작하도록 수행한다. 20과 10이라는 값은 결국 pageNum과 amount를 이용해서 조정되는 값이다. BoardMapper.xml을 수정해서 페이지 번호와 데이터 수를 변경할 수 있게 수정한다.
<!-- paging -->
<select id="getListWithPaging"
resultType="org.zerock.domain.BoardVO">
<![CDATA[
select
bno, title, content, writer, regdate, updatedate
from(
select /*+ INDEX_DESC(tbl_board pk_board)*/
rownum rn, bno, title, content, writer, regdate, updatedate
from
tbl_board
where rownum <= #{pageNum} * #{amount}
)
where rn > (#{pageNum} -1) * #{amount}
]]>
</select>
다시 위에서 작성한 테스트 코드를 조금 수정해서 테스트한다.
// BoardMapperTests.java
@Test
public void testPaging() {
Criteria cri = new Criteria();
// 10개씩 3페이지
cri.setPageNum(3);
cri.setAmount(10);
List<BoardVO> list = mapper.getListWithPaging(cri);
list.forEach(board -> log.info(board));
}
BoardController와 BoardService 수정
페이징 처리는 브라우저에서 들어오는 정보들을 기준으로 동작하기 때문에 Board Controller와 BoardService 역시 전달되는 파라미터들을 받는 형태로 수정해야한다.
BoardService 수정
- BoardService 인터페이스 수정
// 기존 getList() 주석처리
public List<BoardVO> getList(Criteria cri);
- BoardServiceImpl 수정
// 기존 getList() 주석처리
@Override
public List<BoardVO> getList(Criteria cri) {
log.info("get List With Criteria : " + cri);
return mapper.getListWithPaging(cri);
}
- 테스트를 위한 src/test/java/../BoardServiceTests 수정
@Test
public void testGetList() {
//service.getList().forEach(board -> log.info(board));
service.getList(new Criteria(2, 10)).forEach(board -> log.info(board));
}
BoardController 수정
// 기존 list() 주석처리
@GetMapping("/list")
public void list(Criteria cri, Model model) {
log.info("list : " + cri);
model.addAttribute("list", service.getList(cri));
}
- BoardControllerTests 클래스 수정
@Test
public void testListPaging() throws Exception {
log.info(
mockMvc.perform(MockMvcRequestBuilders.get("/board/list")
.param("pageNum", "2")
.param("amount", "50"))
.andReturn()
.getModelAndView()
.getModelMap());
}
- 참고 : 코드로 배우는 스프링 웹 프로젝트
댓글남기기