Spring

스프링 - Part 3 - 기본적인 웹 게시물 관리 07 (MyBatis와 스프링에서 페이징 처리)

록's 2023. 3. 27. 18:26
728x90
반응형

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

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

 

 

org.codehows.domain 패키지에 Criteria 이름의 클래스를 작성한다. Criteria는 검색의 기준을 의미한다.

 

 

Criteria 클래스

// Ctriteria.java

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개로 지정해서 처리한다. Lombok을 이용해서 getter/setter을 생성해준다.

 

 

MyBatis 처리와 테스트

 

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

 

BoardMapper 인터페이스

// BoardMapper.java

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의 BoardMapper.xml에 getListWithPaging에 해당하는 태그를 추가한다.

 

// BoardMapper.xml

... 생략 ...

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

<insert id="insert">
... 생략 ...

 

 

 

페이징 테스트와 수정

 

 

 

BoardMapperTests.java

// BoardMapperTests.java

... 생략 ...

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

 

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

20과 10이라는 값은 결국 pageNum과 amount를 이용해서 조절되는 값이다.

 

 

BoardMapper.xml을 수정해서 페이지 번호(pageNum)와 데이터 수(amount)를 변경 할 수 있게 수정한다.

// BoardMapper.xml

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

 

SQL의 동작에 문제가 없는지 확인해야한다. 이전의 testPaging() 을 수정해서 확인한다.

 

BoardMapperTest.java testPaging() 수정

// 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.getBno()));
	}
}

 

확인을 위해서 Criteria 객체를 생성할 때 파라미터를 추가해보거나, setter를 이용해서 내용을 수정한다. 한페이지당 10개씩 출력하는 3페이지에 해당하는 데이터를 구한 것이다. 테스트 코드가 동작한 후에는 SQL Developer에서 실행된 결과와 동일한지 체크하고 페이지 번호를 변경해서 정상적으로 번호가 처리되는지 확인한다.

 

 

 

 

 

 

BoardController와 BoardService 수정

페이징 처리는 브라우저에서 들어오는 정보들을 기준으로 동작하기 때문에 BoardController 와 BoardService 역시 전달되는 파라미터들을 받는 형태로 수정해야한다.

 

BoardService 수정

 

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

 

 

 

BoardService 인터페이스 수정

// BoardService.java

package org.codehows.service;

import java.util.List;

import org.codehows.domain.BoardVO;
import org.codehows.domain.Criteria;

public interface BoardService {

	public void register(BoardVO board);
	
	public BoardVO get(Long bno);
	
	public boolean modify(BoardVO board);
	
	public boolean remove(Long bno);
	
	//public List<BoardVO> getList();
	
	public List<BoardVO> getList(Criteria cri);
}

 

동일 패키지 내의 BoardServceImpl 클래스 수정.

// BoardServiceImpl.java

... 생략 ... 

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

 

테스트 진행

 

 

BoardServiceTests 클래스 일부 수정

// BoardServiceTests.java

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

 

BoardController 수정

 

기존 BoardController의 list()는 아무런 파라미터가 없이 처리되었기 때문에 pageNum과 amount를 처리하기 위해서 수정한다.

 

// BoardController.java

... 생략 ...

public class BoardController {
   
   private BoardService service;
   
//   @GetMapping("/list")
//   public void list(Model model) {      // void list 형태로 나오게되면 동일한 view의 list.jsp 항목을 호출(이동)
//      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 클래스를 하나 만들어 두면 위와 같이 편하게 하나의 타입만으로 파라미터나 리턴 타입을 사용할 수 있기 때문에 여로모로 편리하다.

 

BoardController 역시 이전에 테스트를 진행했으므로, pageNum과 amount를 파라미터로 테스트한다.

 

 

BoardControllerTests 클래스

// BoardControllerTests.java

... 생략 ...

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

 


 

-- -----------------------------------

/* 현재 시퀀스 번호 확인 */
select seq_board.CURRVAL from dual;
/* 현재 테이블에 복제 전에 데이터 확인*/
select * from tbl_board order by bno desc;

/*시퀀스 번호 삭제*/
drop sequence seq_board;

/* 테이블 bno 최대값이후로 시퀀스 번호 부여*/
create sequence seq_board
start with 101
increment by 1;
728x90
반응형