Mybatis는 SQL을 그대로 사용할 수 있기 때문에 인라인뷰를 이용하는 SQL을 작성하고, 필요한 파라미터를 지정하는 방식으로 페이징 처리를 함.
1) 페이징 번호
2) 한 페이지당 몇 개의 데이터를 보여줄 것인지
페이지번호와 몇 개의 데이터가 필요한지를 별도의 파라미터로 전달하는 방식도 나쁘지않지만, 아예 이 데이타들을 하나의 객체로 묶어서 전달하는 방식이 확장석이 좋음.
1. MyBatis 처리와 테스트
PagingVO.java
package org.project.domain;
import lombok.Data;
@Data
public class PagingVO {
private int pageNum; // 페이지 번호를 나타내는 변수
private int amount; // 페이지 당 항목 수를 나타내는 변수
// 생성자 정의
//생성자는 클래스의 이름과 동일해야 합니다.
//생성자에 반환 타입을 명시하지 않습니다.
//생성자는 객체를 초기화하는 데 사용되며, 객체를 생성할 때 호출된다
public PagingVO(int pageNum, int amount) {
this.pageNum = pageNum; // 페이지 번호 초기화
this.amount = amount; // 페이지 당 항목 수 초기화
}
// 별도의 매개변수가 없으면 페이지 번호와 항목 수를 (1,10)기본값으로 초기화
public PagingVO() {
this(1,10); // PagingVO(1,10)
}
}
BoardMapper.java
public List<BoardVO> getListWithPaging(PagedBoardVO pagedBoardVO); //getPostsByPage(get)
BoardMapper.xml
페이지 번호는 1부터 시작하지만, 데이터베이스의 행은 0부터 시작함
그래서 (pageNum - 1) * amount을 사용하여 페이지 번호가 1일 때는 0 * amount로 0번째부터 시작하게 작성한다.
-- Oracle 데이터베이스에서 사용되는 페이징
<select id="getListWithPaging" resultType="org.project.domain.BoardVO">
<![CDATA[
SELECT bno, title, content, writer, createdDate, updatedDate
FROM
(
<!-- /*+INDEX_DESC(tbl_board pk_board) */ -->
SELECT rownum rn, bno, title, content, writer, createdDate, updatedDate
FROM tbl_board
WHERE rownum <= #{pageNum} * #{amount}
)
WHERE rn > (#{pageNum} -1)* #{amount}
]]>
</select>
-- MySQL 또는 MariaDB와 같은 데이터베이스에서 사용되는 페이징
<select id="getListWithPaging" resultType="org.project.domain.BoardVO">
<![CDATA[
SELECT bno, title, content, writer, createdDate, updatedDate
FROM tbl_board
ORDER BY bno ASC
LIMIT #{amount} OFFSET #{offset}
]]>
</select>
1.1 페이징 테스트와 수정
MyBatis의 #'{}'를 적용하기 전에 XML 설정이 제대로 동작하는지 테스트를 먼저 진행하는 것이 좋다.
BoardMapperTests.java
@Test
public void testPaging() {
PagedBoardVO pagedBoardVO = new PagedBoardVO();
// 페이지 번호와 페이지당 항목 수 설정
pagedBoardVO.setPageNum(2);
pagedBoardVO.setAmount(10);
List<BoardVO> list = mapper.getListWithPaging(pagedBoardVO);
for(int i = 0; i < list.size(); i++) {
BoardVO boardVO = new BoardVO();
boardVO = list.get(i);
log.info(boardVO.getBno());
}
// for(BoardVO boardVO : list) {
// log.info(boardVO.toString());
// }// 향상된 for문
// list.forEach(boardVO -> log.info(boardVO.getBno())); // 람다
}
2. BoardController와 BoardService 수정
페이징 처리는 브라우저에서 들어오는 정보들을 기준으로 동작하기에 BoardController와 BoardService도 파라미터를 받는 형태로 수정한다.
2.1. BoardService 수정
BoardService
public List<BoardVO> getPostsByPage(PagedBoardVO pagedBoardVO); //get(페이징ㅇ)
BoardServiceImpl
@Override
public List<BoardVO> getPostsByPage(PagedBoardVO pagedBoardVO) {
log.info("getPostsByPage.....");
return mapper.getListWithPaging(pagedBoardVO);
}
2.2. BoardContorller 수정
BoardController
@GetMapping("/getPostsByPage") // list.jsp
public void getPostsByPage(Model model, PagedBoardVO pagedBoardVO) {
log.info("getPostsByPage" + pagedBoardVO);
model.addAttribute("getPostsByPage", service.getPostsByPage(pagedBoardVO));
}
BoardControllerTests
@Test
public void testGetPostsByPage() throws Exception {
log.info(mockMvc
.perform(MockMvcRequestBuilders.get("/board/getPostsByPage")
.param("pageNum", "2")
.param("amount", "10"))
.andReturn() // 요청결과를 반환
.getModelAndView() // 반환된 결과에서`ModelAndView`객체를 가져옴
.getModelMap()); // `ModelAndView`에서 모델 정보를 가져옴
}