Part 13. MyBatis와 스프링에서 페이징 처리

  • MyBaits는 SQL을 그대로 사용할 수 있기 때문에 인라인뷰를 이용하는 SQL을 작성하고, 필요한 파라미터를 지정하는 방식으로 페이징 처리를 하게 된다.
  • 여기서 신경 써야 하는 점은 페이징 처리를 위해 SQL을 실행할 때 몇 가지 파라미터가 필요하다는 점이다.
  • 페이징 처리를 위해 필요한 파라미터는 1) 페이지 번호(pageNum), 2) 한 페이지당 몇 개의 데이터(amount)를 보여줄 것인지가 결정되어야만 한다.
  • 페이지 번호와 몇 개의 데이터가 필요한지를 별도의 파라미터로 전달하는 방식도 괜찮지만, 아예 이 데이터들을 하나의 객체로 묶어서 전달하는 방식이 나중을 생각하면 좀 더 확장성이 좋다.
  • org.zerock.domain 패키지에 Criteria 이름의 클래스를 작성한다.
  • Criteria는 '검색의 기준'을 의미한다.
< org.zerock.domain.Critera 클래스 >
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;
	}
}
  • Criteria 클래스의 용도는 pageNum과 amount 값을 같이 전달하는 용도지만 생성자를 통해 기본값을 1페이지, 10개로 지정해서 처리한다.
  • Lombok을 이용해 getter/setter를 생성해 준다.

13.1 MyBatis 처리와 테스트

  • BoardMapper는 인터페이스와 어노테이션을 이용하기 때문에 페이징 처리와 같이 경우에 따라 SQL 구문 처리가 필요한 상황에서는 복잡하게 작성된다. (SQL문이 길어지고 복잡해지면 XML로 처리하는 것이 더 알아보기 쉽고 관리하기 쉬울 수 있다.)
  • org.zerock.mapper 패키지의 BoardMapper에는 위에서 작성한 Criteria 타입을 파라미터로 사용하는 getListWithPaging() 메서드를 작성한다.
< BoardMapper 인터페이스 >
package org.zerock.mapper;
import java.util.List;
import org.apache.ibatis.annotations.Select;
import org.zerock.domain.BoardVO;
import org.zerock.domain.Criteria;
public interface BoardMapper {
	//@Select("select * from tbl_board where bno > 0")	
	// 게시물 조회
	public List<BoardVO> getList();	
	// 게시물 검색 조건
	public List<BoardVO> getListWithPaging(Criteria cri	
	// 게시물 등록
	public void insert(BoardVO board);
	// 게시물 등록
	public void insertSelectKey(BoardVO board);	
	// 특정 게시물 조회
	public BoardVO read(Long bno);	
	// 게시물 삭제
	public int delete(Long bno);	
	// 게시물 업데이트
	public int update(BoardVO board);	
}
  • 기존에 만들어둔 src/main/resources의 BoardMapper.xml에 getListWithPaging에 해당하는 태그를 추가한다.
< BoardMapper.xml - getListWithpaging 태그 추가 >
<!-- getListWithpaging 태그 추가 -->
<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>
  • 작성된 BoardMapper.xml에서는 XML의 CDATA 처리가 들어간다.
  • CDATA 섹션은 XML에서 사용할 수 없는 부등호를 사용하기 위함인데,
    XML을 사용할 경우에는 '<,>'는 태그로 인식하는데, 이로 인해 생기는 문제를 막기 위함이다.(< 나 > 와 같은 특수 문자를 사용할 수도 있긴 하다.)
  • 인라인뷰에서는 BoardVO를 구성하는데 필요한 모든 칼럼과 ROWNUM을 RN이라는 가명을 이용해 만들어주고 바깥쪽 SQL에서는 RN 칼럼을 조건으로 처리한다.

13.1.1 페이징 테스트와 처리

  • MyBatis의 '#{}'를 적용하기 전에 XML 설정이 제대로 동작하는지 테스트를 먼저 진행하는 것이 좋다.
  • 테스트 환경은 이미 준비되어 있으므로 간단히 테스트 코드만을 추가할 수 있다.
  • src/test/java 내에 있는 BoardMapperTests 클래스에 메서드를 추가한다.
< BoardMapperTests - 메서드 추가 >
	// 페이징 처리 테스트
	@Test
	public void testPaging() {		
		Criteria cri = new Criteria();		
		List<BoardVO> list = mapper.getListWithPaging(cri)		  
        list.forEach(board -> log.info(board));
	}
  • Criteria 클래스에서 생성된 객체는 pageNum은 1, amount는 10이라는 기본값을 가지므로 별도의 파라미터 없이 생성한다.
  • 현재는 파라미터의 값이 반영되지 않았으므로 2페이지의 내용이 정상적으로 나오는지 확인한다.
INFO : org.zerock.mapper.BoardMapperTests - BoardVO(bno=5505146, title=새로 작성하는 글 select key, content=새로 작성하는 내용 select key, writer=newbie, regdate=Mon Aug 14 14:20:01 KST 2023, updateDate=Mon Aug 14 14:20:01 KST 2023)
INFO : org.zerock.mapper.BoardMapperTests - BoardVO(bno=5505145, title=새로 작성하는 글 select key, content=새로 작성하는 내용 select key, writer=newbie, regdate=Mon Aug 14 14:20:01 KST 2023, updateDate=Mon Aug 14 14:20:01 KST 2023)
INFO : org.zerock.mapper.BoardMapperTests - BoardVO(bno=5505144, title=새로 작성하는 글, content=새로 작성하는 내용, writer=newbie, regdate=Mon Aug 14 14:20:01 KST 2023, updateDate=Mon Aug 14 14:20:01 KST 2023)
INFO : org.zerock.mapper.BoardMapperTests - BoardVO(bno=5505143, title=새로 작성하는 글, content=새로 작성하는 내용, writer=newbie, regdate=Mon Aug 14 14:20:01 KST 2023, updateDate=Mon Aug 14 14:20:01 KST 2023)
INFO : org.zerock.mapper.BoardMapperTests - BoardVO(bno=5505142, title=테스트 제목, content=테스트 내용, writer=user00, regdate=Mon Aug 14 14:20:01 KST 2023, updateDate=Mon Aug 14 14:20:01 KST 2023)
INFO : org.zerock.mapper.BoardMapperTests - BoardVO(bno=5505141, title=테스트, content=테스트, writer=user00, regdate=Mon Aug 14 14:20:01 KST 2023, updateDate=Mon Aug 14 14:20:01 KST 2023)
INFO : org.zerock.mapper.BoardMapperTests - BoardVO(bno=5505140, title=테스트, content=테스트, writer=user00, regdate=Mon Aug 14 14:20:01 KST 2023, updateDate=Mon Aug 14 14:20:01 KST 2023)
INFO : org.zerock.mapper.BoardMapperTests - BoardVO(bno=5505139, title=수정테스트, content=test
INFO : org.zerock.mapper.BoardMapperTests - BoardVO(bno=5505137, title=새로 작성하는 글 select key, content=새로 작성하는 내용 select key, writer=newbie, regdate=Mon Aug 14 14:20:01 KST 2023, updateDate=Mon Aug 14 14:20:01 KST 2023)

  • SQL에 문제가 없다는 것을 확인했다면 이제 Criteria 객체 내부의 값을 이용해 SQL이 동작하도록 수정한다.
  • 20과 10이라는 값은 결국 pageNum과 amount를 이용해 조절되는 값이다.
  • BoardMapper.xml을 수정해 페이지 번호(pageNum)와 데이터 수(amount)를 변경할 수 있게 수정한다.
< BoardMapper.xml - 페이지 번호, 데이터 수 변경 >
<!-- getListWithpaging 태그 추가 -->
<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>
  • SQL의 동작에 문제가 없는지 확인해야 한다.
  • 이전의 testPaging()을 조금 수정해 확인한다.
< BoardMapperTests의 testPaging() 수정 >
// 페이징 처리 테스트
	@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.getBno()));
	}
  • 확인을 위해서 Criteria 객체를 생성할 때 파라미터를 추가해보거나, setter를 이용해 내용을 수정한다.
  • 위의 경우는 한 페이지당 10개씩 출력하는 3페이지에 해당하는 데이터를 구한 것이다.
  • 테스트 코드가 동작한 후에는 SQL Developer에서 실행된 결과와 동일한지 체크하고 페이지 번호를 변경해서 정상적으로 번호가 처리되는지 확인한다.
INFO : org.zerock.mapper.BoardMapperTests - 5505136
INFO : org.zerock.mapper.BoardMapperTests - 5505135
INFO : org.zerock.mapper.BoardMapperTests - 5505134
INFO : org.zerock.mapper.BoardMapperTests - 5505133
INFO : org.zerock.mapper.BoardMapperTests - 5505132
INFO : org.zerock.mapper.BoardMapperTests - 5505131
INFO : org.zerock.mapper.BoardMapperTests - 5505130
INFO : org.zerock.mapper.BoardMapperTests - 5505129
INFO : org.zerock.mapper.BoardMapperTests - 5505128
INFO : org.zerock.mapper.BoardMapperTests - 5505127

profile
한 걸음 한 걸음 나아가는 개발자

0개의 댓글