☭DEVELOPER/#2 웹개발(자바기반 풀스택)

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

조반짝 2023. 10. 2. 12:26
728x90
반응형

My Batis

쿼리문을 처리하는 MyBatis에 대해 알아보자!

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

 

객체로 묶어서 전달하는 방식 : CRITERIA이름으로 클래스를 작성

 

package org.zerock.domain;

import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

// Criteria는 '검색의 기준'을 의미하는데,
// 여기서는 페이징 처리에 필요한 파라미터인
// 페이지 번호(pageNum), 한페이지당 몇개의 데이터(amount)필드를 정의합니다.

@Getter
@Setter
@ToString
public class Criteria {


	private int pageNum;
	private int amount;
	
	// 아래에서 Criteria 생성자 용도는 
	// pageNum 과 amount 값을 전달받은 생성자 역할을 하며,
	// 기본 값을 1페이지, 10개로 지정해서 처리합니다.
	public Criteria() {
		this(1,10);
	}

	// Source - Generate constructor using fields
	public Criteria(int pageNum, int amount) {
		this.pageNum = pageNum;
		this.amount = amount;
	}
}

My Batis 처리와 테스트

getListWithPageing() 메서드를 작성해서 처리

 

<BoardMapper.java>

// Page294 : Criteria 타입을 파라미터로 사용하는 getListWithPaging() 메서드를 선언해 줍니다.

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 * from tbl_board WHERE bno > 0;
	// mybtis의 애노테이션 방식
//	@Select("select * from tbl_board WHERE bno > 0")	// 마이바티스 애노테이션 활용 DB 정보 SELECT구문
	public List<BoardVO> getlist();
	
	// Page294 : Criteria 타입을 파라미터로 사용하는 getListWithPaging() 메서드를 선언해 줍니다.
	public List<BoardVO> getListWithPaging(Criteria cri);
	
	// xml 형식으로 구현
	// insert만 처리되고 생성된 PK 값을 알 필요가 없는 경우에 활용하는 insert() 추상 메서드 선언
	public void insert(BoardVO board);
	
	// insert문이 실행되고 생성된 PK값을 알아야하는 경우에 활용하는 insertSelectKey() 추상 메서드 선언
	public void insertSelectKey(BoardVO board);
	
	// read(select) 처리를 위한 read() 추상 메서드 정의
	public BoardVO read(Long bno);
	
	// delete 처리를 위한 delete() 추상 메서드 정의
	public int delete(Long bno);

	// update 처리 : 게시물의 업데이트는 제목, 내용, 작성자를 수정 처리 합니다.
	// 업데이트할 때는 최종 수정 시간을 데이터베이스 내 현재 시간으로 수정 처리 합니다.
	// update는 delete와 마찬가지로 "몇 개의 데이터가 수정되었는가"를 처리할 수 있도록
	// int 타입으로 메서드를 설계합니다.
	// update 처리를 위한 update() 추상 메서드 정의
	public int update(BoardVO board);
}

<ORACLE 칼럼 추가적용>

 

 

<BoardMapper.xml>

boardMapper.xml 에서 쿼리 조건문을 넣어준다.

rownum을 기준으로 rownum이 11-20번 까지 기준으로 데이터를 보여달라는 조건을 준다.

 

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >

<!-- MyBatis xml 파일 작성 시 반드시 mapper 태그의 namespace 속성값을
     Mapper 인터페이스와 동일한 이름으로 설정해야 합니다. -->
<mapper namespace="org.zerock.mapper.BoardMapper">
	
   <!-- select 태그의 id 속성값은 메서드의 이름과 일치하게 작성합니다.
      	resultType 속성의 값은 select 쿼리의 결과를 특정 클래스의 객체로
                  만들기 위해서 설정합니다. -->  
	<!-- select * from tbl_board WHERE bno > 0; -->   
	<select id="getlist" resultType="org.zerock.domain.BoardVO">
   	<!-- MyBatis xml 파일 작성에 사용한 CDATA 부분은 XML에서 부등호를
            사용하기 위해서 사용합니다. 쿼리문이 한 눈에 보임, 관리 측면에서 XML활용하기 좋음-->
	<!-- ↓ @SELECT 역할을 함  -->
	<![CDATA[
		select * from tbl_board WHERE bno > 0
	]]>
	</select>
	
   <!-- create(insert) 처리 -->
   <!-- MyBatis는 내부적으로 JDBC의 PreparedStatement를 활용하고,
       	 필요한 파라미터를 처리하는 ?에 대한 치환은 #{속성}을 이용해서 처리합니다. -->
       	 
   <!-- insert만 처리되고 생성된 PK 값을 알 필요가 없는 경우 -->
   <!-- insert into tbl_board (bno, title, content, writer)
		values (seq_board.nextval, '테스트 제목', '테스트 내용', 'user00'); -->
   <insert id="insert">
   		insert into tbl_board (bno, title, content, writer) values (seq_board.nextval, #{title}, #{content}, #{writer})
   </insert>
   
   <!-- insert문이 실행되고 생성된 PK 값을 알아야 하는 경우 -->
   <insert id="insertSelectKey">
   <!-- selectKey는 주로 PK값을 미리(BEFORE) SQL을 통해서 처리해 두고
             특정한 이름으로 결과를 보관하는 방식입니다. -->
      <selectKey keyProperty="bno" order="BEFORE" resultType="long">
      	SELECT seq_board.nextval from dual
      </selectKey>
      	<!-- bno 를 지정하면 select에서  값을 가져옴, 연계값이 있을 때 먼저 만들어진 게시물을 조회하고 처리-->
      	insert into tbl_board (bno, title, content, writer) values (#{bno}, #{title}, #{content}, #{writer})
   </insert>
   
   <!-- read(select) 처리 -->
   <!-- select * from tbl_board where bno =3; -->
   <select id="read" resultType="org.zerock.domain.BoardVO">
   		select * from tbl_board where bno = #{bno}
   </select>
   
   <!-- DELETE 처리 -->
   <!-- delete from tbl_board where bno = 40 -->
   <delete id="delete">
   		delete from tbl_board where bno = #{bno}
   </delete>
   
   <!-- UPDATE 처리 -->
   <!-- 기존에 있는 글을 인지 한 다음에 처리 -->
   <!-- update 칼럼이 최종 수정 시간을 의미하는 칼럼이기 때문에 현재 시간으로 변경해 줍니다.
       	regdate 칼럼은 최초 등록 생성 시간이므로 수정하지 않습니다. #{title}과 같은
              부분은 파라미터로 전달된 BoardVO 객체의 getTitle()과 같은 메서드들을
              호출해서 파라미터들이 처리 됩니다. -->
   <!-- UPDATE tbl_board set title = '수정된 제목', content = '수정된 내용', writer = '김국진', updatedate = sysdate where bno = 5;  -->
   <update id="update">
   		UPDATE tbl_board set title = #{title}, content = #{content}, writer = #{writer}, updatedate = sysdate where bno = #{bno}
   </update>
   
	<!-- 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;
		(ROWNUM이 11 ~ 20 번까지 기준으로 데이터보여줘) 
	-->
   
   
   <!-- Page294 : 아래에 getListWithPageing 메서드 처리 태그르 추가해줍니다-->
   <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>
</mapper>

mybatis 처리와 테스트

 

boardmappertest.java 에서 테스트를 한다.

오라클의 11번- 20번 까지의 bno 넘버와 junit test에 나오는 boardVO가 같은것을 볼 수 있다.

 

<BOARDMAPPERTEST.java>

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 * from tbl_board WHERE bno > 0;
	// mybtis의 애노테이션 방식
//	@Select("select * from tbl_board WHERE bno > 0")	// 마이바티스 애노테이션 활용 DB 정보 SELECT구문
	public List<BoardVO> getlist();
	
	// Page294 : Criteria 타입을 파라미터로 사용하는 getListWithPaging() 메서드를 선언해 줍니다.
	public List<BoardVO> getListWithPaging(Criteria cri);
	
	// xml 형식으로 구현
	// insert만 처리되고 생성된 PK 값을 알 필요가 없는 경우에 활용하는 insert() 추상 메서드 선언
	public void insert(BoardVO board);
	
	// insert문이 실행되고 생성된 PK값을 알아야하는 경우에 활용하는 insertSelectKey() 추상 메서드 선언
	public void insertSelectKey(BoardVO board);
	
	// read(select) 처리를 위한 read() 추상 메서드 정의
	public BoardVO read(Long bno);
	
	// delete 처리를 위한 delete() 추상 메서드 정의
	public int delete(Long bno);

	// update 처리 : 게시물의 업데이트는 제목, 내용, 작성자를 수정 처리 합니다.
	// 업데이트할 때는 최종 수정 시간을 데이터베이스 내 현재 시간으로 수정 처리 합니다.
	// update는 delete와 마찬가지로 "몇 개의 데이터가 수정되었는가"를 처리할 수 있도록
	// int 타입으로 메서드를 설계합니다.
	// update 처리를 위한 update() 추상 메서드 정의
	public int update(BoardVO board);
}

 


여기서 20 은 pageNum * amount =  2(페이지) *  10(데이터양) = 20 

10 은 (pageNum -1)* amount = ( 2(페이지넘버) - 1) * 10(데이터양) = 10

boardmappertest.java

 

오라클과 비교해보면 21부터 30번까지 bno가 같은 걸 볼 수 있다.


BoardController 와 BoardService 수정

 

<BoardService.java>

package org.zerock.service;

import java.util.List;

import org.zerock.domain.BoardVO;
import org.zerock.domain.Criteria;

public interface BoardService {

	// register = insert
	public void register(BoardVO board);
	// get = 상세보기
	public BoardVO get(Long bno);
	// modify = update
	public boolean modify(BoardVO board);
	// remove = delete
	public boolean remove(Long bno);
	
	// Page299 코딩할 때, 아래 1줄 소스는 주석 처리해줍니다.
//	public List<BoardVO> getlList();
	
	// Page299 : 페이징 처리가 적용되는 getList() 메서드 선언
	public List<BoardVO> getList(Criteria cri);
}

<BoardServiceImpl.java>

기능이 추가되어 에러가 뜬다.

package org.zerock.service;

import java.util.List;

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.extern.log4j.Log4j;

@Log4j
@Service // 계층 구조상 주로 비즈니스 영역을 담당하는 객체임을 표시하기 위해 사용함.
@AllArgsConstructor
public class BoardServiceImpl implements BoardService{
	
	// @Setter(onMethod_ = @Autowired)
	// Spring 4.3 이상에서는 단일 파라미터를 받는 생성자의 경우 자동 처리
	// (파라미터를 자동으로 주입할 수 있음. 즉, 위에 @Setter 구문 안써도 됨)
	private BoardMapper mapper;

	@Override
	public void register(BoardVO board) {
		log.info("register 게시글 등록 서비스 실행!" + board);
		mapper.insertSelectKey(board);
		// service > 기능 . mapper  >> mybatis
	}
	
	// 특정 글 상세 조회 작업의 기능 구현
	@Override
	public BoardVO get(Long bno) {
		log.info("get... 특정 글 내용을 조회합니다!" + bno);
		return mapper.read(bno);
	}

	@Override
	public boolean modify(BoardVO board) {
		log.info("modify... 게시글을 수정 처리합니다!" + board);
	      // 정상적으로 수정이 이루어지면 1이라는 값이 반환되기 때문에
	      // '==' 연산자를 이용해서 true/false를 처리할 수 있습니다.
		return mapper.update(board) == 1;
	}

	@Override
	public boolean remove(Long bno) {
		log.info("remove... 게시글을 삭제 처리합니다!" + bno);
		// 정상적으로 수정이 이루어지면 1이라는 값이 반환되기 때문에
		// '==' 연산자를 이용해서 true/false를 처리할 수 있습니다.
		return mapper.delete(bno) == 1;
	}

	// 목록(리스트) 작업의 기능구현
	// Page299 코딩할 때, 아래 5줄 소스는 주석 처리해줍니다.
//	@Override
//	public List<BoardVO> getlList() {
//		log.info("getList... 목록 리스트 정보를 보여줍니다!");
//		return mapper.getlist();
//	}
	
	// Page299 : 페이징 매개변수가 적용된 getList() 메서드 선언
	@Override
	public List<BoardVO> getList(Criteria cri){
		log.info("get List with criteria : " + cri);
		return mapper.getListWithPaging(cri);
	}
	
}

<BoardServiceTests.java>

package org.zerock.service;

import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.fail;

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.zerock.domain.BoardVO;
import org.zerock.domain.Criteria;

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

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("file:src/main/webapp/WEB-INF/spring/root-context.xml")
@Log4j
public class BoardServiceTests {

	@Setter(onMethod_ = {@Autowired})
	private BoardService service;
	
	@Test
	public void testExit() {
		log.info(service);
		assertNotNull(service);
	}
	
	// 등록(regiter) 직업의 기능 구현과 테스트
	@Test
	public void testRegister() {
		BoardVO board = new BoardVO();
		board.setTitle("BoardServiceTests 에서 생성한 새로운 글 제목");
		board.setContent("새로운 글 내용");
		board.setWriter("퐁키");
		
		service.register(board);
		log.info("BoardServiceTests에서 생성된 게시물의 번호 :" + board.getBno());
	}

	// 글목록(리스트) 직업의 기능 구현과 테스트
	@Test
	public void testGetlList() { //백엔드의 getlist와 비슷, 백에서 처리
		// Page300 소스 코딩할때, 아래 1줄 소스는 주석 처리해줍니다
//		service.getlList().forEach(board -> log.info(board));
		
		// Page300 : 페이징 매개변수가 적용된 getList() 메서드 테스트를 합니다.
		service.getList(new Criteria(2,10)).forEach(board -> log.info(board));
	}

	// 특정 글 조회 직업의 기능 구현과 테스트
	@Test
	public void testGet() { // 백엔드의 READ
		// 1번 글의 상세 정보를 로그 정보로 표시해줍니다.
		log.info(service.get(1L));
	}

	// 글 수정 기능 구현 테스트
	@Test
	public void testModify() { // 백엔드의 
		// testModify()의 경우, 특정한 게시글(여기서는 1번글)을 먼저 조회하고,
		BoardVO board = service.get(1L); //1번글 수정 처리
		if (board == null) {
			return;
		}
		// 아래의 소스 코드에서 title 값을 수정한 후에, 이를 업데이트 처리합니다.
		board.setTitle("1번 글의 제목을 수정합니다!");
		log.info("MODIFY RESULT :" + service.modify(board));
	}
	
	// 글 삭제 기능 구현과 테스트
	@Test
	public void testRemove() {
		// 게시물 번호의 존재 여부를 확인하고 테스트를 진행 처리함.
		// testDelete()의 경우, 해당 게시물이 존재할 때 true를 반환하는 것을 확인합니다.
		log.info("REMOVE RESULT : " + service.remove(46L)); // 44번 게시글 삭제처리
	}


}

 


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;
	
//	// Page300 소스코딩 할 때, 아래 5줄 소스는 주석 처리를 해줍니다.
//	@GetMapping("/list")
//	public void list(Model model) {
//		log.info("list 글 목록 조회를 처리합니다!");
//		model.addAttribute("list", service.getlList());
		// 컨트롤러에서 뷰로 데이터 넘길 때 쓰는 뷰모델에 속성명을 추가하여 서비스에 담긴 겟리스트를 list에 담아서 처리함
//	}
	
	// Page300 :  페이징 매개변수 적용 /list 소스 코딩을 아래와 같이 5줄추가합니다.
	@GetMapping("/list")
	public void list(Criteria cri, Model model) {
		log.info("list 글 목록 조회를 처리합니다!" + cri);
		model.addAttribute("list", service.getList(cri));
		
	}
	
	
	
	// Page238 11.3 등록 입력 페이지와 등록 처리
	// 게시물의 등록 작업은 POST방식으로 처리하지만,
	// 화면에서 입력을 받아야 하므로 GET 방식으로 입력 페이지를 볼 수 있도록
	// BoardController에 메서드를 추가해 줍니다.
	// register() 메서드는 입력 페이지를 보여주는 역할만을 하기 때문에
	// 별도의 처리가 필요하지 않습니다.
	@GetMapping("/register")
	public void register() {
		
	}
	
	
	
	@PostMapping("/register") // @PostMapping() POST 방식 URL 메핑
	   // register() 메서드는 String을 리턴 타입으로 지정하고, Redirect Attributes를
	   // 파라미터로 지정합니다. 이것은 등록 작업이 끝난 후 다시 목록 화면으로 이동하기 위함이며,
	   // 추가적으로 새롭게 등록된 게시물의 번호를 같이 전달하기 위해서 RedirectAttributes를
	   // 이용합니다. 이때, 리턴 시에는 "redirect:" 접두어를 사용하는데,
	   // 이것을 이용하면 스프링 MVC가 내부적으로 response.sendRedirect()를 처리해 주기
	   // 때문에 편리합니다.
	public String register(BoardVO board, RedirectAttributes rttr) {
		log.info("regiser(등록): " + board);
		service.register(board);
		rttr.addFlashAttribute("result", board.getBno());
		//redirect : 갱신해서 보내줌
		return "redirect:/board/list";
	}
	
	   // 조회 처리와 테스트 : 등록처리와 유사하게 조회 처리도 BoardController를 이용해서
	   // 처리할 수 있습니다. 특별한 경우가 아니라면 조회는 GET 방식으로 처리하므로,
	   // @GetMapping을 이용합니다.
	   @GetMapping({"/get","/modify"})
	   // BoardController의 get() 메서드에는 bno 값을 좀 더 명시적으로 처리하는
	   // @RequestParam을 이용해서 지정합니다.(파라미터 이름과 변수 이름을 기준으로 동작하기
	   // 때문에 생략해도 됩니다). 또한 화면 쪽으로 해당 번호의 게시물을 전달해야 하므로
	   // Model을 파라미터로 지정합니다.
	   public void get(@RequestParam("bno") Long bno, Model model) {
//		   log.info("/get 조회처리");
		   log.info("/get or modify 조회처리");
		   model.addAttribute("board", service.get(bno));
	   }
	   
	   // 수정 처리와 테스트 : 수정 작업은 등록과 비슷합니다. 변경된 내용을 수집해서
	   // BoardVO 파라미터로 처리하고, BoardService를 호출합니다. 수정 작업을 시작하는
	   // 화면의 경우에는 GET 방식으로 접근하지만 실제 작업은 POST 방식으로 동작하므로
	   // @PostMapping을 이용해서 처리합니다.
	   @PostMapping("/modify")
	   public String modify(BoardVO board, RedirectAttributes rttr) {
		   log.info("modify: 수정 처리" + board);
		   // service.modify() 메서드는 수정 여부를 boolean으로 처리하므로
		   // 이것을 이용해서 성공한 경우에만 RedirectAttributes에 추가합니다.
		   if (service.modify(board)) {
			   rttr.addFlashAttribute("result","success");
		   }
		   return "redirect:/board/list";
	   }
	   // 삭제 처리와 테스트 : 삭제 처리도 조회와 유사하게 BoardController와 테스트 코드를
	   // 작성합니다. 삭제는 반드시 POST 방식으로만 처리합니다.
	   @PostMapping("/remove")
	   public String remove(@RequestParam("bno") Long bno, RedirectAttributes rttr) {
		   log.info("remove : 삭제 처리 " + bno);
		      // BoardController의 remove() 메서드는 삭제 후 페이지의 이동이 필요하므로
		      // RedirectAttributes를 파라미터로 사용하고, 'redirect'를 이용해서
		      // 삭제 처리 후에 다시 목록 페이지로 이동 처리 합니다.
		   if (service.remove(bno)) {
			rttr.addFlashAttribute("result", "success");
		}
		   return "redirect:/board/list";
	   }
}

 

<BoardControllerTests.java>

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 lombok.Setter;
import lombok.extern.log4j.Log4j;

// 스프링의 테스트 기능을 활용하면 개발 당시에 Tomcat(WAS)을 실행하지 않고도
// 스프링과 웹 URL을 테스트할 수 있습니다. WAS를 실행하지 않기 위해서는 약간의 추가적인 코드가
// 필요하지만 반복적으로 서버를 실행하고 화면에 입력하고, 오류를 수정하는 단계를 줄여줄 수 있기
// 때문에 Controller를 테스트할 때는 한번쯤 고려해 볼 필요가 있습니다.
@RunWith(SpringJUnit4ClassRunner.class)
// Test for Controller : @WebAppConfiguration은 Servlet의 ServletContext를
// 이용하기 위해서 사용하며, 스프링에서는 WebApplicationContext를 이용하기 위해 선언합니다.
@WebAppConfiguration
@ContextConfiguration({
 "file:src/main/webapp/WEB-INF/spring/root-context.xml",
 "file:src/main/webapp/WEB-INF/spring/appServlet/servlet-context.xml"})
@Log4j
public class BoardControllerTests {
	  
		@Setter(onMethod_ = {@Autowired})
	   private WebApplicationContext ctx;
	   // MockMvc는 '가짜 mvc'라고 생각하시면 됩니다. 가짜로 URL과 파라미터 등을 브라우저에서
	   // 사용하는 것처럼 만들어서 Controller를 실행해 볼 수 있습니다.
	   private MockMvc mockMvc;
	   // @Before 적용된 메서드는 모든 테스트 전에 매번 실행되는 메서드가 됩니다.
	   // @Before 어노테이션이 적용된 setup()에서는 import할 때 JUnit을 사용해야 합니다.
	   @Before
	   public void setup() {
	      this.mockMvc = MockMvcBuilders.webAppContextSetup(ctx).build();
	   }
	   
	   // testList()는 MockMvcRequestBuilders을 이용 해서 GET 방식 호출을 합니다
	   @Test
	   public void testList() throws Exception{
		   log.info(
				   mockMvc.perform(MockMvcRequestBuilders.get("/board/list"))
				   .andReturn()
				   .getModelAndView()
				   .getModelMap()
				   );
	   }
	   
	   //Page301 : 페이징 매개변수 적용 testListPaging() 메서드 선언
	   @Test
	   public void testListPaging() throws Exception{
		   log.info(mockMvc.perform(MockMvcRequestBuilders.get("/board/list")
				   .param("pageNum", "2")
				   .param("amount", "10"))
				   .andReturn().getModelAndView().getModelMap());
				   
	   }
	   
	// 테스트할 때 MockMvcRequestBuildersd의 post()메서드를 이용하면 POST 방식으로
	// 데이터를 전달할 수 있고, param()을 이용해서 전달해야 하는 파라미터들을 지정할 수 있습니다.(<input>태그와 비슷한 역할을 함)

	@Test
	public void testRegister() throws Exception{
		String resultPage = 
				mockMvc.perform(MockMvcRequestBuilders.post("/board/register")
						.param("title", "컨트롤러 활용 등록 테스트 새글 목록입니다!")
						.param("content", "컨트롤러 활용 등록 테스트 새글 내용입니다!")
						.param("writer", "김다미")
						).andReturn().getModelAndView().getViewName();
		log.info(resultPage);
	}
	
	// 특정 게시물을 조회할 때는 'bno' 파라미터가 필요하므로 param() 메서드를 활용해서
	// 추가하고 실행합니다. 마지막에는 Model에 담겨 있는 BoardVO 인스턴스의 내용을 볼 수 있습니다.
	@Test
	public void testGet() throws Exception{
		log.info(mockMvc.perform(MockMvcRequestBuilders
				.get("/board/get")
				.param("bno", "5"))
				.andReturn()
				.getModelAndView().getModelMap());
	}
	
	@Test
	public void testModify() throws Exception{
		String resultPage =
				mockMvc.perform(MockMvcRequestBuilders.post("/board/modify")
						.param("bno", "1")
						.param("title", "컨트롤러 활용 수정처리된 제목 입니다!")
						.param("content", "컨트롤러 활용 수정 처리된 내용 입니다!")
						.param("writer", "이영애")
						).andReturn().getModelAndView().getViewName();
			log.info(resultPage);
	}
	
	// 삭제 처리의 테스트 코드는 위에 등록 처리 소스 코드와 유사합니다.
	@Test
	public void testRemove() throws Exception{
	      // MockMvc를 이용해서 파라미터를 전달할 때에는 문자열로만 처리해야 합니다.
	      // 그리고, 삭제 테스트 전에 데이터베이스에서 게시물의 번호가 존재하는지
	      // 확인하고 테스트를 실행합니다.
		String resultPage =
				mockMvc.perform(MockMvcRequestBuilders.post("/board/remove")
						.param("bno", "43")
						).andReturn().getModelAndView().getViewName();
		log.info(resultPage);
	}
}

 


페이징 화면 처리

domain > PageDTO 생성

<PageDTO.java>

PageDTO_Test.class 생성

getPageNum()를 3으로 나눈다. 

총 10개가 한페이지가 보여지고 11개 가 되면 다음 페이지로 넘어감

package org.zerock.domain;

public class PageDTO_Test {

	public static void main(String[] args) {
		
		// 1페이지의 경우 : Math.ceil(0.1) * 10 = 1.0 * 10 =10
		// 3페이지의 경우 : Math.ceil(0.3)  = 1.0 
		System.out.println(3/10.0); //3페이지를 10.0으로 나눈다. cri.getPageNum()를 3으로 가정함
		System.out.println(Math.ceil(0.1));  //1.0
		System.out.println((Math.ceil(0.3)*10));  //10.0
		
		// endPage
		System.out.println((int)(Math.ceil(0.3)*10));  //10
		int endPage = (int)(Math.ceil(0.3)*10);
		// startPage
		int startPage = endPage - 9;
		System.out.println(startPage);
	} 

}

12페이지일 경우

 

realEnd page

 

728x90
반응형