[Spring] 영속 계층의 CRUD 구현을 위한 환경설정
영속 계층의 작업은 항상 다음과 같은 순서로 진행합니다.
1. 테이블의 컬럼 구조를 반영하는 VO(Value Object) 클래스의 생성
2. MyBatis의 Mapper 인터페이스의 작성/XML 처리
3. 작성한 Mapper 인터페이스의 테스트
지난 글에 다음과 같은 구조로 테이블을 작성했습니다. 해당 테이블을 다시 사용하려고 합니다.
https://lifere.tistory.com/130
테이블 구조는 다음과 같습니다.
1. 테이블의 컬럼 구조를 반영하는 VO(Value Object) 클래스의 생성
com.project.domain 패키지를 생성하고 하위에 BoardVO 클래스를 생성합니다. 테이블의 컬럼 구조를 반영하는 변수들을 작성하고, Lombok을 이용해서 생성자와 getter/setter, toString() 등을 만들어 내는 방식을 사용합니다. 이를 위해 @Data 어노테이션을 적용합니다.
2. MyBatis의 Mapper 인터페이스의 작성/XML 처리
1) 먼저 MyBatis의 Mapper 인터페이스, XML 파일을 작성하기 전에 스프링에서 MyBatis를 활용할 수 있도록 Mapper 스캔을 설정합니다.
스프링을 xml 설정 구조로 가져갔다면,
root-context.xml 파일에 'com.project.mapper' 패키지를 스캔(조사)하도록 설정합니다.
<mybatis-spring:scan base-package="com.project.mapper"/>
스프링을 java 설정 구조로 가져갔다면,
RootConfig 클래스에 'com.project.mapper' 패키지를 스캔(조사)하도록 설정합니다.
@MapperScan(basePackages = {"com.project.mapper"})
2) MyBatis는 SQL을 처리하는데 어노테이션이나 XML을 이용할 수 있습니다.
간단한 SQL이라면 어노테이션을 이용해서 처리하는 것이 무난하지만, SQL이 복잡하고 검색과 같이 상황에 따른 다른 SQL문이 처리되는 경우 어노테이션은 그다지 유용하지 못하다는 단점이 있습니다. XML의 경우 단순 텍스트를 수정하는 과정만으로 처리가 끝나지만, 어노테이션의 경우 코드를 수정하고 다시 빌드하는 등의 유지 보수성이 떨어지는 이유로 기피하는 경우도 종종 있습니다.
Mapper 인터페이스
package com.project.mapper;
import java.util.List;
import org.apache.ibatis.annotations.Select;
import com.project.domain.BoardVO;
public interface BoardMapper {
@Select("SELECT * FROM tb_board WHERE seq_bno > 0")
public List<BoardVO> getList();
}
BoardMapper Interface를 작성할 때 이미 작성된 BoardVO 클래스를 활용해서 필요한 SQL을 어노테이션의 속성값으로 처리할 수 있습니다.(SQL을 작성할 때는 반드시 ';'이 없도록 작성해야 합니다.)
작성한 SQL문을 SQL 관리하는 TOOL 쿼리창이나 콘솔에서 먼저 결과를 확인하고 사용합니다. SQL이 문제가 없이 실행 가능한지를 확인하기 위함과 데이터베이스의 commit을 하지 않았다면 나중에 테스트 결과가 달라지기 때문에 이를 먼저 비교할 수 있도록 하기 위함입니다.
SQL 결과
3. 작성한 Mapper 인터페이스의 테스트
작성된 BoardMapper 인터페이스를 테스트 할 수 있게 테스트 환경인 'src/test/java'에 'com.project.mapper' 패키지를 작성하고 BoardMapperTests 클래스를 추가합니다.
BoardMapperTests 클래스
package com.project.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 com.project.config.RootConfig;
import lombok.Setter;
import lombok.extern.log4j.Log4j;
@RunWith(SpringJUnit4ClassRunner.class)
//@ContextConfiguration("file:src/main/webapp/WEB-INF/spring/root-context.xml")
@ContextConfiguration(classes = {RootConfig.class}) // Java Config
@Log4j
public class BoardMapperTests {
@Setter(onMethod_ = @Autowired)
private BoardMapper mapper;
@Test
public void testGetList() {
mapper.getList().forEach(board->log.info(board));
}
}
BoardMapperTests 클래스는 스프링을 이용해서 BoardMapper 인터페이스의 구현채를 주입받아서 동작하게 합니다. Java 설정 시에는 RootConfig 클래스를 이용해서 스프링의 설정을 이용하고 있음을 명시합니다. testGetList()의 결과는 SQL 문을 직접 실행된 것과 동일해야만 정상적으로 동작한 것입니다.
JUnit Test Execute -> Result
(2번 내용 이어서)
Mapper XML 파일 작성
BoardMapperTests를 이용해서 테스트가 완료되었다면 src/main/resources 내에 패키지와 동일한 com/project/mapper 단계의 폴더를 생성하고 XML 파일을 작성합니다. BoardMapper.xml
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="com.project.mapper.BoardMapper">
<select id="getList" resultType="com.project.domain.BoardVO">
<![CDATA[
select * from tb_board where seq_bno > 0
]]>
</select>
</mapper>
XML을 작성할 때는 반드시 <mapper>의 namespace 속성 값을 Mapper 인터페이스와 동일한 이름을 주는 것에 주의하고, <select> 태그의 id 속성 값은 메서드의 이름과 일치하게 작성합니다. resultType 속성의 값은 select 쿼리의 결과를 특정 클래스의 객체로 만들기 위해서 설정합니다. XML에 사용한 CDATA 부분은 XML에서 부등호를 사용하기 위해서 사용합니다.
기존에 생성했던 BoardMapper 인터페이스에 SQL은 제거합니다. (어노테이션 제거) 그리고 테스트 코드를 통해 기존과 동일하게 동작하는지 확인해야 합니다.
실행결과
BoardMapper.xml에 작성한 쿼리도 같은 결과를 확인할 수 있습니다.
다음은 실제로 영속 영역의 CRUD 구현을 알아보겠습니다.
'java, spring' 카테고리의 다른 글
[Spring framework] 비즈니스 계층 CRUD (0) | 2021.06.24 |
---|---|
[Spring] 영속 영역의 CRUD 구현 (MyBatis - CRUD) (0) | 2021.06.21 |
[Spring framework] 스프링 MVC 프로젝트 Java로 구성하기 (0) | 2021.06.18 |
[Spring framework] 데이터베이스 연결 테스트 코드 (0) | 2021.06.17 |
[Spring Framework] SQLSessionFactory (0) | 2021.06.11 |