영속 계층의 CRUD 구현

charco·2021년 4월 2일
0

제목의 생소한 단어들 때문에 어려워 보일 수 있지만
쉽게 말해 Spring MVC 에서 데이터베이스를 읽고, 삭제하고, 쓰고, 수정하는 것이다.

우리는 게시판을 만들 것이기 때문에
Board 라는 이름을 기반으로 클래스를 작성할 것이다.

영속 계층의 CRUD 구현을 위해 필요한 파일들

1.BoardVO 클래스
이 클래스에는 테이블의 칼럼을 참고해 변수들을 선언해 놓는다.

2.BoardMapper 인터페이스
이 인터페이스는 CRUD 를 위한 메서드의 반환 타입, 이름만 선언한다.

3.BoardMapper.xml
이 파일에서는 SQL query 문들이 들어간다.
BoardMapper 인터페이스에서 선언된 메서드들의 실질적인 내용들을 작성한다.

4.BoardMapperTests
src/test/java 폴더에 생성한다.
위 세개의 클래스들이 정상적으로 기능하는지 테스트 하기 위함이다.

본격적인 구현

VO 객체 생성

@Data
public class BoardVO {
	//오라클에 있는 테이블의 구성에 따라 변수를 선언
	private Long bno;
	private String title;
	private String content;
	private String writer;
	private Date regDate;
	private Date updateDate;
}코드를 입력하세요

CRUD 구현

BoardMapper.java

import java.util.List;

import org.apache.ibatis.annotations.Select;
import org.zerock.domain.BoardVO;

//이 인터페이스에서는 메서드의 선언만 하고 그 실질적인 내용은 XML 에 작성한다.
public interface BoardMapper {
	//select 쿼리를 객체 배열 형태로 저장
	//@Select("select * from tbl_board where bno > 0")
	public List<BoardVO> getList();
	
	//Write 이므로 반환값이 필요 없음
	//데이터 생성 후 PRIMARY KEY를 알 필요가 없을때
	public void insert(BoardVO board);
	//데이터 생성 후 PRIMARY KEY를 알아야 할 떄
	public void insertSelectKey(BoardVO board);
	
	//Read(select)
	//반환타입을 해당 객체로 하고 PRIMARY KEY를 파라미터로 받아서 조회한다.
	public BoardVO read(Long bno);
	
	//Delete
	//삭제 된 Row가 있으면 1, 아니면 0을 반환
	public int delete(Long bno);
	
	//Update
	//위와 마찬가지로 업데이트 된 Row 가 있으면 1, 아니면 0 을 반환
	public int update(BoardVO board);
}

BoardMapper.xml

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

  <!-- mapper 의 namespace를 해당 매퍼 이름과 동일하게 해야 한다. -->
  <mapper namespace="org.zerock.mapper.BoardMapper">
  <!-- select태그의 id 는 메서드 이름, resultType 은 쿼리의 결과를 특정 클래스의 객체로 만들기 위해 설정 -->
  <select id="getList" resultType="org.zerock.domain.BoardVO">
  <![CDATA[
  	select * from tbl_board where bno > 0
  ]]>
  </select>
  
  <!-- 단순히 시퀀스의 다음값을 구해서 insert, 몇개의 데이터가 변경되었는지만을 알려줌 -->
  <insert id="insert">
  	insert into tbl_board (bno, title, content, writer)
  	<!-- #{?} 는 BoardVO 객체의 field(변수) 를 받는다 -->
  	values(seq_board.nextval, #{title}, #{content}, #{writer})
  </insert>
  
  <!-- SQL문을 통해 PK값을 미리(BEFOER) 처리 후 특정한 이름으로 결과를 보관함 -->
  <insert id="insertSelectKey">
  	<selectKey keyProperty="bno" order="BEFORE" resultType = "Long">
  		select seq_board.nextval from dual
  	</selectKey>
  	insert into tbl_board (bno, title, content, writer)
  	values(#{bno}, #{title}, #{content}, #{writer})
  </insert>
  
  <!-- read 메서드 -->
  <select  id="read"  resultType = "org.zerock.domain.BoardVO">
  <!-- PRIMARY KEY(bno) 를 이용해 조회 -->
  	select * from tbl_board where bno = #{bno}	
  </select>
  
  <!-- delete 메서드 -->
  <delete id="delete">
  	delete from tbl_board where bno = #{bno}
  </delete>
  
  <!-- update 메서드 -->
  <update id="update">
  	update tbl_board 
  	set title = #{title},
  	content = #{content},
  	writer = #{writer},
  	updateDate = sysdate
  	where bno = #{bno}
  </update>
  </mapper>코드를 입력하세요

BoardMapperTests.java

package org.zerock.mapper;

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

@RunWith(SpringJUnit4ClassRunner.class)
//RootConfig 클래스를 이용해 스프링의 설정을 이용하고 있음을 명시
@ContextConfiguration(classes = {org.zerock.config.RootConfig.class}) 
@Log4j
public class BoardMapperTests {
	//BoardMapper 를 의존성 주입 , 객체 생성
	@Setter(onMethod_= @Autowired)
	private BoardMapper mapper;
	
	@Test
	public void testGetList() {
		//객체에서 getList() 메서드를 불러와 forEach 로 iterate 시키며 콘솔에 출력
		mapper.getList().forEach(board -> log.info(board));
	}
	
	@Test //Insert 메서드 테스트
	public void testInsert() {
		//BoardVO 객체 생성
		BoardVO board = new BoardVO();
		//BoardVO field 추가
		board.setTitle("새로 작성하는 글");
		board.setContent("새로 작성하는 내용");
		board.setWriter("user001");
		//mapper 객체의 insert 메서드 의 파라미터로 위의 객체를 줌
		mapper.insert(board);
		
		log.info(board);
	}
	
	@Test //InsertSelectKey 메서드 테스트
	public void testInsertSelectKey() {
		//BoardVO 객체 생성
		BoardVO board = new BoardVO();
		//BoardVO field 추가
		board.setTitle("새로 작성하는 글");
		board.setContent("새로 작성하는 내용");
		board.setWriter("user001");
		//mapper 객체의 insert 메서드 의 파라미터로 위의 객체를 줌
		mapper.insertSelectKey(board);
		
		log.info(board);
	}
	
	@Test
	public void testRead() {
		//read 메서드는 BoardVO 타입의 결과를 반환한다.
		//그 결과는 BoardVO 객체에 담긴다.
		BoardVO board = mapper.read(5L);
		log.info(board);
	}
	
	@Test
	public void testDelete() {
		
		log.info("DELETE COUNT: " +mapper.delete(3L));
	}
	
	@Test
	public void testUpdate() {
		//VO 객체를 생성하고 update 하기 위한 데이터를 담는다
		BoardVO board = new BoardVO();
		board.setBno(5L);
		board.setTitle("수정된 제목");
		board.setContent("수정된 내용");
		board.setWriter("user001");
		//count 에 update의 결과를 저장 (1 or 0)
		int count = mapper.update(board);
		log.info("UPDATE COUNT: " + count);
	}
}
profile
아직 배우는 중입니다

0개의 댓글