본문 바로가기

개발 공부/Spring

코드로 배우는 스프링 웹 프로젝트-13.MyBatis와 스프링에서 페이징 처리

코드로 배우는 스프링 웹 프로젝트-13.MyBatis와 스프링에서 페이징 처리

코드로 배우는 스프링 웹 프로젝트 - 개정판

2019년 7월 10일 인쇄판

 

 

Part3. 기본적인 웹 게시물 관리

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

 

페이징 처리를 위해 필요한 파라미터는 페이지 번호(pageNum), 한 페이지당 몇 개의 데이터(amount)를 보여줄 것인지이다.

 

org.zerock.domain 패키지에 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;
	}
}

Criteria 클래스 용도는 pageNum과 amount를 전달하는 용도

 

 

13.1 MyBatis 처리와 테스트

 

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

 

org.zerock.mapper 패키지의 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);
}

xml에 추가

 

<select id="getListWithPaging" resultType="org.zerock.domain.BoardVO">
	<![CDATA[
		select
			bno, title, content
		from 
		(
 		   select /*+ INDEX_DESC(tbl_board pk_board) */
 		   	rownum rn, bno, title, content
  		  from
   		 	tbl_board
   		 where rownum<=20
    	)
		where rn > 10;
	]]>
</select>

 

 

13.1.1 페이징 텍스트와 수정

 

MyBatis의 #{}를 적용하기 전에 XML 테스트 실행

BoardMapperTests에 추가

 

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

<select id="getListWithPaging" resultType="org.zerock.domain.BoardVO">
	<![CDATA[
		select
			bno, title, content
		from 
		(
 		   select /*+INDEX_DESC(tbl_board pk_board) */
 		   	rownum rn, bno, title, content
  		  from
   		 	tbl_board
   		 where rownum<= #{pageNum} * #{amount}
    	)
		where rn > (#{pageNum}-1) *  #{amount}
	]]>
</select>

 

최종적으로 xml을 위와 같이 수정.

 

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

 

 

13.2 BoardController와 BoardService 수정

 

13.2.1 BoardService 수정

 

Criteria를 파라미터로 처리하도록 수정.

package org.zerock.service;

import java.util.List;

import org.zerock.domain.BoardVO;
import org.zerock.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);
}
package org.zerock.service;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.zerock.domain.BoardVO;
import org.zerock.domain.Criteria;
import org.zerock.mapper.BoardMapper;

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

@Service
@AllArgsConstructor
@Log4j
public class BoardServiceImpl implements BoardService{
	@Setter(onMethod_ = @Autowired)
	private BoardMapper mapper;
	//spring 4.3 이상에선 자동 처리
	
	
	@Override
	public boolean modify(BoardVO board) {
		// TODO Auto-generated method stub
		log.info("modify....." + board);
		return mapper.update(board) == 1;
	}

	@Override
	public boolean remove(Long bno) {
		// TODO Auto-generated method stub
		log.info("remove....." + bno);
		return mapper.delete(bno) == 1;
	}

	/*
	@Override
	public List<BoardVO> getList() {
		// TODO Auto-generated method stub
		log.info("getList.....");
		return mapper.getList();
	}
*/
	@Override
	public void register(BoardVO board) {
		// TODO Auto-generated method stub
		log.info("register....." + board);
		mapper.insertSelectKey(board);
	}

	@Override
	public BoardVO get(Long bno) {
		// TODO Auto-generated method stub
		log.info("get......" + bno);
		return mapper.read(bno);
	}

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

}

 

BoardServiceTests 테스트)

 

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

 

 

13.2.2 BoardController 수정

 

package org.zerock.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import org.zerock.domain.BoardVO;
import org.zerock.domain.Criteria;
import org.zerock.service.BoardService;

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

@Controller
@Log4j
@RequestMapping("/board/*")
@AllArgsConstructor
public class BoardController {
	private BoardService service;
	
	/*
	@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));
	}
	
	@PostMapping("/register")
	public String register(BoardVO board, RedirectAttributes rttr) {
		log.info("register : " + board);
		service.register(board);
		rttr.addFlashAttribute("result", board.getBno());
		return "redirect:/board/list";
	}
	
	@GetMapping({"/get", "/modify"})
	public void get(@RequestParam("bno") Long bno, Model model)
	{
		log.info("/get or modify");
		model.addAttribute("board", service.get(bno));
	}
	
	@PostMapping("/modify")
	public String modify(BoardVO board, RedirectAttributes rttr) {
		log.info("modify: " + board);
		if(service.modify(board)) {
			rttr.addFlashAttribute("result", "sucess");
		}
		return "redirect:/board/list";
	}
	
	@PostMapping("/remove")
	public String remove(@RequestParam("bno") Long bno, RedirectAttributes rttr) {
		log.info("remove..." + bno);;
		if(service.remove(bno))
		{
			rttr.addFlashAttribute("result", "success");
		}
		return "redirect:/board/list";
	}
	
	@GetMapping("/register")
	public void register() {
		
	}
}

getList에 대하여 수정한다.

 

BoardControllerTests 클래스 수정

 

package org.zerock.controller;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
import org.zerock.domain.BoardVO;

import lombok.Setter;
import lombok.extern.log4j.Log4j;

@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration	//Test for Controller
@ContextConfiguration({
	"file:src/main/webapp/WEB-INF/spring/root-context.xml",
	"file:src/main/webapp/WEB-INF/spring/appServlet/servlet-context.xml"
})
//Java Config
//@ContextConfiguration(classes={org.zerock.config.RootConfig.class, org.zerock.config.ServletConfig.class})
@Log4j
public class BoardControllerTests {
	@Setter(onMethod_ = {@Autowired})
	private WebApplicationContext ctx;
	
	private MockMvc mockMvc;
	
	@Before
	public void setup() {
		this.mockMvc = MockMvcBuilders.webAppContextSetup(ctx).build();
	}
	
	
	/*
	@Test
	public void testList() throws Exception {
		log.info(
				mockMvc.perform(MockMvcRequestBuilders.get("/board/list"))
				.andReturn()
				.getModelAndView()
				.getModelMap());
	}
	
	
	
	@Test
	public void testRegister() throws Exception {
		String resultPage = mockMvc.perform(MockMvcRequestBuilders.post("/board/register")
				.param("title", "테스트 새글 제목")
				.param("content", "테스트 새글 내용")
				.param("writer", "user00")
				).andReturn()
				.getModelAndView()
				.getViewName();
		log.info(resultPage);
	}
	
	
	@Test
	public void testGet() throws Exception {
		log.info(mockMvc.perform(MockMvcRequestBuilders
				.get("/board/get")
				.param("bno", "10"))
				.andReturn()
				.getModelAndView()
				.getModelMap());
	}
	
	
	
	
	@Test
	public void testModify() throws Exception {
		String resultPage = mockMvc
				.perform(MockMvcRequestBuilders
						.post("/board/modify")
						.param("bno", "10")
						.param("title", "수정된 테스트 글 제목")
						.param("content", "수정된 테스트 글 내용")
						.param("writer", "user00"))
				.andReturn()
				.getModelAndView()
				.getViewName();
		
		log.info(resultPage);
	}
	
	
	
	@Test
	public void testRemove() throws Exception {
		String resultPage = mockMvc
				.perform(MockMvcRequestBuilders
						.post("/board/remove")
						.param("bno",  "5"))
				.andReturn()
				.getModelAndView()
				.getViewName();
		
		log.info(resultPage);
	}*/
	
	
	@Test
	public void testList() throws Exception {
		log.info(
				mockMvc.perform(MockMvcRequestBuilders.get("/board/list")
						.param("pageNum", "2")
						.param("amount", "50"))
				.andReturn()
				.getModelAndView()
				.getModelMap());
	}
	
}