본문 바로가기

BackEnd/Spring

[코드로 배우는 스프링 웹 프로젝트] ch13 MyBatis와 스프링에서 페이징 처리(Criteria)

728x90
반응형

◎ MyBatis 스프링 페이징 처리

   ▷ MyBatis는 SQL을 그대로 사용할 수 있기 때문에 인라인뷰를 이용하는 SQL을 작성하고 필요한 파리미터 지정하는 방식으로 페이징 처리

   ▷ 필요한 파라미터

      ▶ 페이지 번호

      ▶ 한 페이지당 보여줄 데이터 수

   ▷ 페이지 번호와 몇 개의 데이터가 필요한지 별도의 파라미터로 전달하는 방식도 좋지만 이 데이터들을 하나의 객체로 묶어 전달하는 방식이 확장성이 좋음

 

◎ src/main/java → org.codehows.domain  Criteria 클래스 작성

   ▷ Criteria : 검색의 기준을 의미

package org.codehows.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개로 지정해서 처리

 

 

1. MyBatis 처리와 테스트

   ▷ BoardMapper는 인터페이스와 어노테이션 이용하기 떄문에 페이징 처리와 같이 경우에 따라 SQL 구문처리가 필요한 상황에서 복잡하게 작성됨

 

◎ src/main/java → org.codehows.mapper BoardMapper 클래스 수정

   ▷ Criteria 타입을 파라미터로 하는 getListWithPaging() 메소드 작성

package org.codehows.mapper;

import java.util.List;

import org.codehows.domain.BoardVO;
import org.codehows.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 → org.codehows.mapper  BoardMapper.xml 내용 추가

   ▷ getListWithPaging()에 해당하는 태그 추가

<select id="getListWithPaging" resultType="org.codehows.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>

 

(1) 페이징 테스트와 수정

   ▷ MyBatis '#{}'를 적용하기 전에 XML 설정이 제대로 동작하는지 테스트 먼저 진행하는 것이 좋음

 

◎ src/test/java → org.codehows.mapper → BoardMapperTests 클래스에 메소드 추가

...(생략)...
	@Test
	public void testPaging() {
		Criteria cri = new Criteria();
		
		List<BoardVO> list = mapper.getListWithPaging(cri);
		
		list.forEach(board -> log.info(board));
	}
}


실행시키면 아래와 같이 내림차순으로 10개가 출력되는 것을 볼 수 있습니다.

 

◎ src/main/resources → org.codehows.mapper  BoardMapper.xml 내용 수정

   ▷ SQL에 문제가 없다는 것을 확인했으면 Criteria 객체 내부의 값을 이용해 SQL이 동작하도록 수정

   ▷ 페이지 번호(pageNum), 데이터 수(amount)를 변경할 수 있게 수정

   ▷ getListWithPaging() 내용 변경

<select id="getListWithPaging" resultType="org.codehows.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>

 

◎ src/test/java → org.codehows.mapper → 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()));
	}
}


한 페이지당 10개씩 출력하는 3페이지에 해당하는 데이터를 구한 것


코드 지정시 위의 그림과 같이 페이지별로 개수가 출력이 됩니다.

 

 

2. BoardController와 BoardService 수정

   ▷ 페이징 처리는 브라우저에서 들어오는 정보들을 기준으로 동작하기 때문에 전달되는 파라미터들을 받는 형태로 수정 필요

 

(1) BoardService 수정

   ▷ BoardService는 Criteria를 파라미터로 처리하도록 BoardService 인터페이스와 BoardServiceImpl 클래스 수정


1. BoardService 인터페이스 수정

public interface BoardService {
	... (생략) ...
	// public List<BoardVO> getList();
	
	public List<BoardVO> getList(Criteria cri);
}



2. BoardServiceImpl 클래스 수정

package org.codehows.service;

import java.util.List;

import org.codehows.domain.BoardVO;
import org.codehows.domain.Criteria;
import org.codehows.mapper.BoardMapper;
import org.springframework.stereotype.Service;

import lombok.AllArgsConstructor;
import lombok.extern.log4j.Log4j;

@Log4j
@Service
@AllArgsConstructor
public class BoardServiceImpl implements 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);
	}
}



3. src/test/java → org.codehows.service → BoardServiceTests.java 클래스 수정

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

 

 

(2) BoardController 수정

   ▷ BoardController의 list()는 아무런 파라미터 없이 처리되었으므로 pageNum과 amount 처리하기 위해 수정


◎ BoardController 클래스 수정

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

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



Criteria 클래스를 하나 만들어두면 위와 같이 편리하게 하나의 타입만으로 파타미터 리턴 타입을 사용할 수 있음



◎ BoardControllerTests 클래스 수정

...(생략)...
// 추가
	@Test
	public void testListPaging() throws Exception{
		log.info(mockMvc.perform(
			MockMvcRequestBuilders.get("/board/list")
			.param("pageNum", "2")
			.param("amount", "50"))
			.andReturn().getModelAndView().getModelMap());
	}
}


콘솔로 출력하면 2페이지의 50개가 출력이 됩니다.

 

페이지 처리를 할 수 있는 Criteria 클래스를 먼저 작성한 후 BoardMapper 클래스에 페이징 처리를 위한 함수를 생성하고 xml에 SQL을 사용할 수 있는 구문을 추가합니다.

 

마지막으로 테스트 페이지에 추가해서 실행해주면 원하는 결과를 출력할 수 있습니다.

 

이렇게 페이징 처리하는 방법에 대해서 배워보았고 다음 시간에는 페이징 화면 처리하는 방법에 대해서 배워볼게요!!

 

많은 분들의 피드백은 언제나 환영합니다!  많은 댓글 부탁드려요~~

 

728x90
반응형