2017년 7월 18일 화요일

Spring Boot + MyBatis 프로젝트 설정하기

 Spring Boot를 이용하면 MyBatis도 매우 간단하게 연동해서 사용할 수 있다. 어떤 라이브러리(프레임워크)든지 프로젝트에 추가하려고 할 때 내가 가장 먼저 관심을 갖는 것은 가능한 최소한의 설정이 무엇인가 이다. 일단은 가장 최소한의 설정으로 기본적인 기능을 그대로 이용해보고 필요한 추가 설정이 생기면 그때그때 조금씩 수정해가는 것이 가장 깔끔한 상태를 유지하는 길이라고 생각하기 때문이다.

 Spring Boot와 MyBatis를 함께 사용하는 것은 그러한 측면으로는 정말 최소한의 설정만으로 큰 만족을 얻을 수 있다.

 일단 IntelliJ IDEA CE버전으로 기본적인 Spring Boot 프로젝트를 생성하도록 하자. (생성방법은 이전 글을 참고하기 바란다.) 최초 생성 직후의 build.gradle 파일의  dependency는 'spring-boot-starter'가 들어가 있겠지만 MyBatis를 이용하려면 아래와 같이 'mybatis-spring-boot-starter'로 교체해준다.
dependencies {
    compile('org.mybatis.spring.boot:mybatis-spring-boot-starter:1.3.0')
    compile('org.mariadb.jdbc:mariadb-java-client:2.0.3')
    testCompile('org.springframework.boot:spring-boot-starter-test')
}
 사실 이전 글의 생성방법에 따라 프로젝트를 생성할 때 Spring Initializr화면을 Full Version으로 전환한 후 MyBatis 체크박스에 체크를 하면 'spring-boot-starter' 대신 'mybatis-spring-boot-starter'가 dependency에 들어간다. 하지만 이렇게 기본 생성된 파일을 직접 수정해줘도 똑같다.

 추가로 JDBC 드라이버를 dependency에 추가해주어야 한다. 위의 예에서는 MariaDB의 JDBC 드라이버를 넣어주었지만 각자 자신의 DB에 맞는 드라이버를 설정해주도록 하자.

 다음으로 'src/main/resources/'에 있는 application.properties 파일에 data source를 설정해주도록 하자. (파일이 없으면 만들어준다.) data source가 설정이 되어있지 않으면 예외가 발생하면서 정상적으로 실행되지 않으므로 반드시 해주어야 한다.
spring.datasource.driver-class-name=org.mariadb.jdbc.Driver
spring.datasource.url=jdbc:mysql://192.168.0.33:3306/Test
spring.datasource.username=testuser
spring.datasource.password=testpass
 각 항목에 대한 설명은 굳이 하지 않아도 JDBC 유 경험자라면 다들 알만한 것들이다. 자신의 DB 생성 상황에 맞게 위 값들을 맞춰서 넣어주도록 하자. (당연히 'Test' DB와 'testuser' 사용자 계정 같은 것들은 DB에 준비가 되어 있어야 한다.)

 일단 설정 파일 수정 사항은 이게 끝이다. 이렇게 data source 설정만으로 MyBatis를 사용할 수 있으니 최소한의 설정임에 틀림이 없는 것 같다.

 이제 Java 코드에 손 댈 차례다. 먼저 Mapper로 사용할 Interface를 만들어 준다.
package com.company.dbtest.mapper;

import org.apache.ibatis.annotations.Mapper;

@Mapper
public interface TestMapper {
    String getTime();
}
 mapper들을 모아 놓을 package (com.company.dbtest.mapper)에 TestMapper 인터페이스를 위와 같이 선언해서 넣어놓는다.

 다음으로 프로젝트 생성 시 같이 생성된 @SpringBootApplication 클래스를 열어서 아래와 같이 수정해준다.
package com.company.dbtest;

import com.company.dbtest.mapper.TestMapper;
...

@SpringBootApplication
@MapperScan("com.company.dbtest.mapper")
public class DbtestApplication implements CommandLineRunner {

 @Autowired
 TestMapper testMapper;

 public static void main(String[] args) {
  SpringApplication.run(DbtestApplication.class, args);
 }

 @Override
 public void run(String... args) throws Exception {
  System.out.println("Time:" + testMapper.getTime());
 }
}
 수정 내용을 살펴보면 먼저 @MapperScan 어노테이션을 추가해주었다. 여기서 지정된 "com.company.dbtest.mapper" 패키지에서 자동으로 mapper를 찾아서 사용할 것이므로 정확하게 지정하도록 한다.

 이제 TestMapper 인터페이스를 @Autowired로 직접 주입받아서 바로 사용이 가능하다. 위 예에서는 주입받은 testMapper를 run()함수에서 직접 사용하고 있다.

 물론 아직 실행은 안된다. 아직 TestMapper의 getTime()에서 실행할 SQL문을 아직 정의하지 않았기 때문이다. MyBatis가 찾아서 사용할 Mapper XML 파일을 추가해 주어야 한다. 별다른 설정을 하지 않았기 때문에 MyBatis는 mapper 인터페이스와 같은 classpath에서 같은 이름의 xml파일을 찾아서 사용하려고 할 것이다. TestMapper 인터페이스와 같은 classpath(com.company.dbtest.mapper)에 TestMapper.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.hansdesk.dbtest.mapper.TestMapper">
    <select id="getTime" resultType="String">
        SELECT NOW()
    </select>
</mapper>
 mapper의 자세한 정의 방법은 MyBatis의 문서를 참고하도록 하고 간단히 설명하자면 mapper 태그의 namespace에 TestMapper 인터페이스의 Full name을 지정하고 select 태그의 id로 메소드의 이름을 지정한 것이다. getTime()이 호출되면 DB에서 "SELECT NOW()"가 실행되어 시간 문자열이 반환된다.

 참고로 IntelliJ를 사용할 때의 주의사항 한 가지를 얘기해야 겠다. xml 파일이 mapper 인터페이스와 같은 패키지에 있으면 MyBatis가 같은 이름의 xml파일을 자동으로 찾아서 사용하지만 IntelliJ에서 디버깅할 때 xml파일이 'src/main/java' 폴더 아래에 있으면 찾지 못한다. 반드시 아래 그림과 같이 'src/main/resources' 폴더에 mapper package와 같은 경로를 만들어서 xml 파일을 넣어놓도록 하자. 'src/main/java' 폴더 아래 mapper 패키지에 xml파일을 넣어놓으면 찾지 못하고 예외가 발생한다. 양쪽 어디에 있건 Jar로 묶어 놓으면 같은 package에 들어가게 되지만 IntelliJ에서 디버깅할 때 만큼은 다르게 인식되는 것 같다.

0 개의 댓글:

댓글 쓰기