ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [3-ch13 게시판] MyBatis와 스프링에서 페이징 처리하기
    Back-End/Spring Legacy 2022. 8. 28. 11:36

     

     

    이전 포스팅에서 힌트(hint)와 ROWNUM, 인라인뷰를 사용해서 원하는 값을 추출하는 방법을 알아봤다. 그렇다면 직접 웹 페이지에 적용하기 위해 MyBatis에 적용하는 법을 알아보려 한다. 페이징 처리 관련 내용은 아래 링크 클릭! 

     

    https://wonisdaily.tistory.com/62

     

    [3-ch12 Spring web 게시판] 페이징 처리, 힌트(hint), ROWNUM & 인라인뷰 적용

    order by의 문제 데이터의 양이 많을수록 정렬이라는 작업은 많은 리소스를 소모한다. 데이터베이스를 이용할 때 웹이나 애플리케이션에서 가장 신경쓰는 부분은 1) 빠르게 처리되는 것, 2) 필요한

    wonisdaily.tistory.com

     

     

    MyBatis는 SQL을 그대로 사용할 수 있기 때문에 인라인 뷰를 이용하는 SQL을 작성하고, 필요한 파라미터를 지정하는 방식으로 페이징 처리를 하게 된다. 여기서 신경 써야 하는 점은 페이징 처리를 위해 SQL을 실행할 때 몇 가지 파라미터가 필요하다는 점이다. 페이징 처리를 위해 필요한 파라미터는 아래와 같다.

     

    1. 페이지 번호(pageNum)
    2. 한 페이지당 몇 개의 데이터(amount)를 보여줄 것인가.

     

    페이지 번호와 몇 개의 데이터가 필요한지를 별도의 파라미터로 전달하는 방식도 나쁘지 않지만, 아예 이 데이터들을 묶어서 객체로 전달하는 방식이 확장성이 더 좋기에 org.zerock.domain 패키지에 Criteria 이름의 클래스를 작성한다. Criteria는 '검색의 기준'을 의미한다.

     

     

     

    <Criteria 클래스>

    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;
    	}
    }

     

     

     

    MyBatis 처리와 테스트

     

    BoardMapper는 인터페이스와 어노테이션을 이용하기 때문에 페이징 처리와 같이 경우에 따라 SQL 구문 처리가 필요한 상황에서는 복잡하게 작성된다. (SQL문이 길어지고 복잡해지면 XML로 처리하는 것이 더 알아보기 쉽고 관리하기도 쉽다.) 

     

    BoardMapper.java 클래스에 List 목록을 조회하는 getListWithPaging(Criteria cri) 메서드를 추가 작성한다. 

     

    package org.zerock.mapper;
    
    import java.util.List;
    
    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);
    
    }

     

     

     

    BoardMapper.xml에 해당하는 메서드의 태그를 추가한다.

     

    <!-- 페이징 처리 목록 조회 -->
    <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>

     

     

    테스트 메서드에서 테스트를 실행해본다.

     

    @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이라는 기본값을 가지므로 별도의 파라미터 없이 생성하며, 현재는 파라미터의 값이 지정되지 않았으므로 20과 10이라는 숫자 그대로 값이 조회된다. 

     

    따라서 파라미터의 값을 받고 싶다면! xml의 select 태그에서 #{}로 값을 받아야 한다.

     

     

     

    <BoardMapper.xml>

    <!-- 페이징 처리 목록 조회 -->
    <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>

     

     

    테스트 코드도 수정해서 실행해본다.

    @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));
    
    }

     

     

    이번엔 Criteria 객체를 생성해 파라미터를 추가하거나, setter를 이용해 내용을 수정한다. 우의 경우는 한 페이지당 10개씩 출력하는 3페이지에 해당하는 데이터를 구한 것이다. 

     

    아래는 service를 수정한 다음 테스트 한 코드인데 Criteria 객체를 생성해 파라미터를 추가한 모습이다. 위에는 setter로 값 변경.! 둘은 같은 값을 초래함으로 비교해서 알아두자. 

     

    @Test
    public void testGetList() {
    //		Criteria cri = new Criteria();
    //		cri.setAmount(10);
    //		cri.setPageNum(2);
    //		service.getList(cri).forEach(board -> log.info(board));
        service.getList(new Criteria(2,10)).forEach(board -> log.info(board));
    }

     

     


     

    BoardService, BoardController 수정

     

     

     BoardService와 BoardContorller의 인터페이스와 클래스에 getList를 수정하는데 파라미터로 Criteria cri 값을 받도록 변경한다.! 

     

     

    <BoardService>

    //	@Override
    //	public List<BoardVO> getList(){
    //		
    //		log.info("getList............");
    //		return mapper.getList();
    //	}
    
    @Override
    public List<BoardVO> getList(Criteria cri){
    
        log.info("get List with criteria............ + cri");
        return mapper.getListWithPaging(cri);
    }

     

     

    <BoardController>

    //   @GetMapping("/list")
    //   public void list(Model model) {
    //      log.info("list");
    //      model.addAttribute("list", service.getList());
    //   }
    
    @GetMapping("/list")
    public void list(Model model, Criteria cri) {
      log.info("list");
      model.addAttribute("list", service.getList(cri));
    }

     

     

    반응형

    댓글

Designed by Tistory.