본문 바로가기
개발입문/SPRING 게시판 만들기

[SPRING] 테이블 CRUD 구현

by 양히◡̈ 2022. 10. 12.

SQL Developer 에서 테이블 만들고 연동 테스트하기

sql developer를 실행하여 admin 계정으로 접속한 후 아래 쿼리문을 작성한다.

// 게시판 테이블을 만들고 시퀀스로 일련번호를 만들고 만든 후 프라이머리키를 만드는 작업

CREATE SEQUENCE seq_board;

CREATE TABLE tbl_board (
    bno        NUMBER(10, 0),
    title      VARCHAR2(200) NOT NULL,
    content    VARCHAR2(2000) NOT NULL,
    writer     VARCHAR2(50) NOT NULL,
    regdate    DATE DEFAULT sysdate,
    updatedate DATE DEFAULT sysdate
);

ALTER TABLE tbl_board ADD CONSTRAINT pk_board PRIMARY KEY ( bno );

-- 아래 insert문은 5번 반복 실행하여 동일행 5개 추가하기
INSERT INTO tbl_board (
    bno,
    title,
    content,
    writer
) VALUES (
    seq_board.NEXTVAL,
    '테스트 제목',
    '테스트 내용',
    'user00'
);

COMMIT;

시퀀스를 생성할 때는 데이터베이스의 다른 오브젝트와 구분하기 위해서 'seq_'로 시작하는 것이 일반적이다.

마찬가지로 테이블은 'tbl_' 또는 't_'로 시작하는 것이 좋다.

테이블 생성 후, alter를 이용해서 pk_board라는 프라이머리키를 bno에 부여했다.

테스트를 위해 insert문을 5번 반복하여 동일한 행을 5개 추가한다.

sql developer의 admin 계정 아래에 새로운 테이블이 생성되었고, 테스트 게시물도 5개가 생성된 것을 확인할 수 있다.

 

 

다시 STS로 돌아와서,

src/main/java > new Class 생성 > Package: kr.icia.domain / name: BoardVO

파일 안에 아래 코드를 입력한다.

package kr.icia.domain;

import java.util.Date;

import lombok.Data;

@Data
public class BoardVO {
	private Long bno;
	private String title;
	private String content;
	private String writer;
	private Date regdate;
	private Date updateDate;
}

@Data (작성 후 ctrl+shift+O)

이 어노테이션을 작성하면 화면 우측 상단에 있는 Outline에서 메소드를 자동으로 생성해주는 것을 확인할 수 있다.

Lombok을 이용한 생성자와 getter,setter,toString()을 만들어내는 것이다.

@Data 어노테이션 사용시 ​

 

 

 

이제 쿼리 조작을 위한 mapper.xml을 만들 것이다.

기존에 root-context.xml에서 <mybatis-spring:scan base-package="kr.icia.mapper" /> 코드를 추가했었기 때문에,

해당 경로에 존재하는 mapper를 스캔하여 활용할 수 있게 되었다.

src/main/resources > kr > icia > mapper > new XML file 생성 > name: BoardMapper.xml

BoardMapper.xml 파일을 실행하여 TimeMapper.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 코드를 아래대로 입력한다.

<mapper namespace="kr.icia.mapper.BoardMapper">
	<select id="getList" resultType="kr.icia.domain.BoardVO">
	<![CDATA[ 	
	select *from tbl_board where bno > 0
	]]>
	<!-- ![CDATA[내용]] 는 xml에서 <,> 같은 기호가 들어가도 코드로 오해하지 말라는 기능 -->
	</select>
</mapper>

 

 

src/main/java > kr.icia.mapper > new Interface 생성 > name: BoardMapper

package kr.icia.mapper;

import java.util.List;

import kr.icia.domain.BoardVO;

public interface BoardMapper {
	public List<BoardVO> getList();
}

 

 

이제 생성된 인터페이스를 확인하기 위해 테스트 클래스를 만든다.

src/test/java > new Class 생성 > package: kr.icia.mapper / name: BoardMapperTests

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

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("file:src/main/webapp/WEB-INF/spring/root-context.xml")
@Log4j
public class BoardMapperTests {
		@Setter(onMethod_ = @Autowired)
		private BoardMapper mapper;
		//BoardMapper 객체가 초기화됨

		@Test
		public void testGetList() {
			mapper.getList().forEach(board -> log.info(board));
			//forEach문 : 리스트 내에 있는 거 하나를 board 변수에 담는다
			//-> 우항의 조건을 리스트 원소가 없을 때까지 반복한다
		}
}

 

지금까지 만든 내용을 종합해 보면,

BoardVO 클래스를 만들어 변수를 담았고, BoardMapper.java 에서 getList 메소드를 만들었으며,

BoardMapper.xml 에서 getList를 매핑하고, BoardMapperTests에서 메소드를 호출하였다.

이제 JUnit Test 를 구동하면 콘솔에 다음과 같은 화면이 보여진다.

 

 

 

테이블 CRUD(생성/읽기/수정/삭제) 구현하기

이제 메소드를 만들어 CRUD를 구현해볼 것이다.

BoardMapper.java 파일 getList() 아래에 내용을 추가한다.

package kr.icia.mapper;

import java.util.List;

import kr.icia.domain.BoardVO;

public interface BoardMapper {
	public List<BoardVO> getList();
	//목록 가져오기
	
	public void insert(BoardVO board);
	//bno는 시퀀스 자동생성으로 나머지 값만 입력
	//새로운 게시물 1개 추가
	
	public void insertSelectKey (BoardVO board);
	//생성되는 시퀀스 값을 확인하고 나머지 값 입력
	//새로운 게시물 1개 추가의 다른 방식
	
	public BoardVO read(Long bno);
	//게시물 내용 읽기
	
	public int delete(Long bno);
	//게시물 삭제
	
	public int update(BoardVO board);
	//게시물 수정
	
	//crud: create(insert) read(select) update delete
}

 

BoardMapper.xml 파일에서 Mapper 코드 안에 있는 Select 코드 아래에 내용을 추가한다.

<?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="kr.icia.mapper.BoardMapper">
	<select id="getList" resultType="kr.icia.domain.BoardVO">
	<![CDATA[ 	
	select *from tbl_board where bno > 0
	]]>
		<!-- ![CDATA[내용]] 는 xml에서 <,> 같은 기호가 들어가도 코드로 오해하지 말라는 기능 -->
	</select>


	<insert id="insert">
		insert into tbl_board(bno, title, content, writer)
		values (seq_board.nextval, #{title}, #{content}, #{writer})
	</insert>

	<insert id="insertSelectKey">	
	<!-- insert와 동일하나, insert 실행 전 selectKey를 먼저 실행한다 -->
		<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>

	<select id="read" resultType="kr.icia.domain.BoardVO">
		select * from tbl_board where
		bno=#{bno}
	</select>

	<delete id="delete">
		delete tbl_board where bno=#{bno}
	</delete>

	<update id="update">
		update tbl_board
		set title=#{title},
		content=#{content},
		writer=#{writer},
		updateDate=sysdate
		where bno=#{bno}
	</update>
</mapper>

 

 

1) Insert

그 다음 BoardMapperTests.java 로 가서 아래처럼 메소드를 호출하고 JUnit Test를 해본다.

(Run As 하기 전, 이전에 Test했던 부분은 주석처리 후 진행하는 게 좋다.)

	@Test
	public void testInsert() {
		BoardVO board = new BoardVO();
		board.setTitle("새로 작성하는 글");
		board.setContent("새로 작성하는 내용");
		board.setWriter("새로운 작성자");
		
		mapper.insert(board);
		log.info(board);
	}

그러면 아래와 같은 결과가 콘솔에 출력된다.

sql developer 에도 정상적으로 추가된 것을 볼 수 있다.

 

2) InsertSelectKey

이번에는 똑같은 Tests 클래스파일에서 이전 Test를 주석처리한 후 testInsertSelectKey() 를 호출해본다.

	@Test
	public void testInsertSelectKey() {
		BoardVO board = new BoardVO();
		board.setTitle("새로 작성하는 글 SelecetKey");
		board.setContent("새로 작성하는 내용 SelecetKey");
		board.setWriter("새로운 작성자 SelecetKey");
		
		mapper.insertSelectKey(board);
		log.info(board);
	}

 

3) Read

전과 동일한 방법으로 Test 메소드를 작성 및 구동해본다.

	@Test
	public void testRead() {
		BoardVO board = mapper.read(21L);
		//L은 bno가 long타입이라는 것을 알림
		log.info(board);
	}

 

4) Delete

	@Test
	public void testDelete() {
		log.info("delete cnt: " + mapper.delete(61L));
	}

삭제 성공시 삭제된 레코드 개수를 리턴하고, 실패시 0을 리턴한다.
sql developer 에도 삭제가 된다.

 

 

5) Update

	@Test
	public void testUpdate() {
		BoardVO board = new BoardVO();
		board.setBno(5L);
		board.setTitle("수정된 제목");
		board.setContent("수정된 내용");
		board.setWriter("user00");
		
		int count = mapper.update(board);
		log.info("update cnt : " + count);
	}

 

 
 
 
 
 

댓글