Kim VamPa

[Spring][05-2]MyBatis 사용(Mapper 인터페이스, Mapper XML) 본문

공부/스프링

[Spring][05-2]MyBatis 사용(Mapper 인터페이스, Mapper XML)

Kim VamPa 2020. 4. 13. 04:04
728x90
반응형

개인 공부 후 자료를 남기기 위한 목적이기에 내용 상에 오류가 있을 수 있습니다.

git주소(Oracle DB) : https://github.com/sjinjin7/blog_study

git주소(MySQL DB) : https://github.com/sjinjin7/blog_study-MYSQL-base-


목표

  • MyBatis사용하기 위해서 Mapper 인터페이스와 Mapper XML의 구조가 필요합니다.
  • 따라서 이번 포스팅에선 Mapper 인터페이스와 Mapper XML 형태를 생성 및 설정을 마지막으로 테스트까지 진행하겠습니다.
  • Mapper 인터페이스를 통한 맵핑과 Mapper XML을 통한 맵핑의 장단점에 대해 알아보겠습니다.

목차

1. Mapper 인터페이스

2. Mapper XML

 

 

0. 들어가기 앞서

 SQLSessionFactory를 이용해서 코드를 직접 작성하더라도 직접 Connection 객체를 얻어서 JDBC 코딩이 가능합니다.  하지만 좀 더 편하게 작업하기 위해선 SQL을 어떻게 처리할 것인지를 별도의 설정을 분리해 주고, 자동으로 처리되는 방식을 사용하는 것이 좋습니다. 이를 실현시키기 위해선 MyBatis의 Mapper라는 존재가 필요합니다. 

 여기서 말하는 Mapper는 SQL과 그에 대한 처리를 지정하는 역할을 수행합니다. 스프링에서 MyBatis를 사용하는 경우에는 Mapper를 인터페이스(Mapper 인터페이스+어노테이션) 형태와 XML(Mapper XML) 형태로 작성할 수 있습니다. 

1. Mapper 인터페이스

 MyBatis-Spring은 Mapper 인터페이스를 이용해서 실제 SQL 처리가 되는 클래스를 자동으로 생성합니다. 

Mapper 인터페이스 생성 및 설정 방법

1) mapper로 사용할 패키지 추가

 : src/main/java 경로에 com. 자신의 프로젝트명. mapper 패키지를 추가시켜줍니다.

- 저 같은 경우 com.vam.mapper를 생성하였습니다.

- 해당 패키지에 mapper로 사용할 인터페이스(Interfate)를 생성하여 사용하시면 됩니다.

그림 1-1

 

 

2) root-context.xml 설정

: 1)에선 mapper 인터페이스를 넣을 패키지를 만들었습니다. 그 안에 인터페이스를 생성한다고 해서 스프링은 해당 패키지안의 인터페이스를 mapper로 인식하지 않습니다. root-context.xml에 추가적인 설정을 통해 패키지에 생성한 인터페이스를 mapper로 인식하도록 만들어야 합니다.

 

가. root-context.xml 창을 엽니다. 하단 namespaces를 클릭 후 뜨는 목록에서 mybatis-spring을 체크하여 추가해줍니다.

그림 1-2

 

나. 다시 하단에 Source를 클릭한 후 아래의 코드를 추가해줍니다. 
- <mybatis-spring:scan> 태그의 base-package 속성은 지정된 패키지의 모든 MyBatis 관련 어노테이션을 찾아서 처리합니다. 

<mybatis-spring:scan base-package="자신이 mapper 인터페이스를 담을 패키지 지정"/>

그림 1-3

 

테스트

 앞서 Mapper 인터페이스를 생성하고 설정하였습니다. 이번엔 이 구조를 직접 사용해보도록 하겠습니다. 아직 데이터베이스에 테이블을 생성하지 않은 관계로 테이블 없이도 실행이 되는 SQL문(select sysdate from dual [현재시간])을 사용하는 것을 목표로 하겠습니다. 

 

1)  root-context.xml에 mapper역할로 지정한 패키지(전 com.vam.mapper입니다.)에 테스를 위해 사용할 인터페이스 TimeMapper.java를 만듭니다.

- 클래스가 아니라 인터페이스를 만들어야 합니다.

그림 1-4

 

2) 인터페이스에 아래의 코드를 추가시켜 줍니다. 

- 어노테이션을 이용해서 SQL을 메서드에 추가합니다.

package com.vam.mapper;

import org.apache.ibatis.annotations.Select;

public interface TimeMapper {

	@Select("SELECT sysdate FROM dual")
	public String getTime();
	
}

그림 1-5

 

3) SQL문이 작동하는지 테스트를 위해서 "src/test/java" => "com.vam.persistence" 경로에 TimeMapperTests 클래스를 만듭니다. 

그림 1-6

 

4) 아래의 테스트 코드를 추가합니다.

package com.vam.persistence;

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.vam.mapper.TimeMapper;

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

	@Autowired
	private TimeMapper timeMapper;
	
	@Test
	public void testGetTime() {
		System.out.println(timeMapper.getTime());
	}
	
	
}

그림 1-7


5) JUnit을 통해서 테스트를 진행합니다.

그림 1-8

 

6) 결과를 확인합니다.

그림 1-9

 

그림 1-10

- Console창을 보시면 Mapper에서 작성한 SQL문이 정상 작동했다는 것을 보실 수 있습니다. 

 

 

 

2.  Mapper XML

 Mapper 인터페이스만으로도 충분히 SQL문을 편리하게 처리가 가능합니다. 하지만 복잡하고 길어지는 SQL문을 사용하는 경우에는 XML문을 사용해야 합니다. 앞서 추가한 MyBatis-Spring 라이브러리 경우 Mapper 인터페이스와 XML을 동시에 이용할 수 있습니다.

 Mapper XML을 사용하기 위해 가장 주의해야 할 점은 XML 파일의 위치와 XML 파일에서 지정하는 namespaces 속성입니다. 

 

* 인터페이스와 XML을 동시에 사용하는 경우 Mapper 인터페이스 단독으로 사용하였을 때 작성한 어노테이션은 사용하지 않습니다. 

Mapper XML 생성 및 설정 방법

 

XML 저장 위치 :

 저장 방법은 두 가지입니다.

1. Mapper 인터페이스가 저장된 곳에 xml파일을 저장시켜도 됩니다.

2. 'src/main/resources' 위치에 Mapper 인터페이스가 저장된 패키 지명을 폴더 경로로 만들어줍니다.

 

XML 파일 명 : 

 XML 파일을 만들 때 정해진 규칙은 없습니다. 그렇지만 가능하면 Mapper인터페이스와 같은 이름을 이용하여 가독성을 높여주는 것이 좋습니다.

 

실습

목표 : 

- XML 저장 위치를 src/main/resources에 만들어보도록 하겠습니다.

- 기존에 만들었던 TimeMapper인터페이스와 연동되는 xml파일을 만들겠습니다.

 

 

1. 저의 인터페이스 경로는 'com.vam.mapper'이기 때문에 'src/main/resources'경로에 com/vam/mapper 경로가 되도록 폴더를 만들어줍니다.

그림 2-1
그림 2-2

 

2. 생성한 경로에 TimeMapper 인터페이스와 이름이 동일한 TimeMapper.xml파일을 만듭니다.

 

가. 파일을 추가할 경로를 선택 후 오른쪽 마우스를 클릭 =>[New] => [Other]를 클릭합니다.

그림 2-3

 

나. 검색 박스에 'xml'을 기입 한합니다. 결과 물 중 "XML File"을 클릭 =>[next]를 클릭합니다.

그림 2-4

 

다. 자신이 사용할 파일명을 작성한 후 [Finish] 버튼을 클릭합니다.

그림 2-5

라. xml파일 생성이 완료되었습니다. 

그림 2-6

 

3. 아래의 코드를 xml파일에 추가해줍니다. 

- <! DOCTYPE> 태그는 해당 문서가 mapper로서의 역할을 한다고 명시되어 있습니다.  mapper로서 xml을 사용하고 싶으시다면 반드시 작성되어야 합니다.

- <mapper> 태그에서 namespace 속성을 여러분이 연동시키고자 하는 Mapper 인터페이스명을 경로와 함께 명시 해주셔야합니다. 

- SQL문은 <mapper>태그 안에 작성해주시면 됩니다. xml파일에서 SQL문 사용방법에 대한 자세한 내용은 MyBatis 공식 홈페이지를 참고부탁드립니다.

<?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.vam.mapper.TimeMapper">
  
  
  </mapper>

그림 2-7

 

이로써 사용하기 위한 설정은 모두 완료되었습니다. 만든 구조를 정상적으로 작동이 되는지 직접 테스트해보겠습니다.

 

테스트

 기존에 사용하였던 TimeMapper 인터페이스에서 추가적인 메서드를 선언하여 사용해보겠습니다. 

 

목표 : 

- 인터페이스만을 사용한 메서드(getTime())을 그대로 두고 새로운 메서드(getTime2)를 추가하겠습니다 해당 메서드는 XML 파일을 통해 SQL문이 실행되도록  하겠습니다.

 

1. TimeMapper 인터페이스에 getTime2() 메서드를 추가해줍니다. 

package com.vam.mapper;

import org.apache.ibatis.annotations.Select;

public interface TimeMapper {

	@Select("SELECT sysdate FROM dual")
	public String getTime1();
	
	public String getTime2();
	
}

그림 2-8

 

2. TimeMapper.xml 파일에 <select> 태그를 작성하고 실행시키고자 하는 SQL문(현재시간)을 추가합니다.

- <mapper> 태그에 id속성은 Mapper인터페이스에 추가한 메서드명과 동일 하게 작성됩니다.

- <mapper>태그에 resultType속성은 연동시킬 메서드에 명시된 반환 타입을 작성해줍니다.

- <mapper>태그 내부에 SQL문을 작성합니다. => SELECT sysdate FROM dual(현재시간 검색)

- 자세한 사용방법은 MyBatis 공식 홈페이지를 참고하시면 됩니다.

<?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.vam.mapper.TimeMapper">
  
  	<select id="getTime2" resultType="string" >
  		SELECT sysdate FROM dual
  	</select>
  
  </mapper>

그림 2-9

 

3. 기존에 테스트를 위해 사용하였던 TimeMapperTests 클래스에 테스트를 위한 코드를 추가해줍니다.

package com.vam.persistence;

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.vam.mapper.TimeMapper;

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

	@Autowired
	private TimeMapper timeMapper;
	
	@Test
	public void testGetTime() {
		System.out.println(timeMapper.getTime1());
	}
	
	@Test
	public void testGetTime2() {
		System.out.println(timeMapper.getTime2());
	}
	
	
}

그림 2-10

 

4. Junit테스트를 진행해줍니다.

그림 2-11

 

5. 결과창을 확인합니다.

- 콘솔 창을 확인해보시면 두 개의 현재시간 문구가 떠 잇는 것을 보실 수 있습니다.

- 위의 문구는 getTime1() 메서드의 결과입니다. 오로지 인터페이스와 어노테이션을 사용해서 SQL문을 실행시켰습니다.

- 아래의 문구는 getTime2() 메서드의 결과입니다. 해당 메서드는 인터페이스와 XML 파일을 통해서 SQL문을 실행시켰습니다.(어노테이션은 사용되지 않았습니다.)

그림 2-12

 

그림 2-13

 

3.  정리

 MyBatis를 통해서 SQL문을 실행하기 위해선 두 가지 방법이 있습니다. 첫 번째 방법은 인터페이스와 어노테이션 사용입니다. 두 번째 방법은 인터페이스와 XML사용입니다. 첫 번째 장점은 인터페이스 파일 한 가지만 사용함으로써 매우 편리하게 SQL을 실행시킬 수 있습니다. 하지만 길고 복잡한 SQL문은 사용할 수 없다는 단점이 있습니다. 길고 복잡한 SQL문을 사용해야 할 경우 XML을 사용하는 두 번째 방식을 사용해야 합니다.

 XML방식을 사용하여야 할 때는 '파일 생성 위치'와 xml파일에서 작성하는 'namespace'속성을 주의하여 작성해야 합니다. 제대로 된 위치와 제대로된 namespace속성을 작성하지 못할 시엔 반드시 에러가 발생하기 때문입니다. 

 xml을 통한 더 세부적인 사용 방법은 MyBatis 공식 홈페이지를 참고하시면 됩니다.

 

 

 

Reference

Date

  • 2020.04.12 작성

 

 

 

 

728x90
반응형
Comments