MyBatis | Spring Boot와 연계

Spring Boot 용 플러그인이 포함되어 있기 때문에, 이를 사용하면 간단하게 연계할 수 있다.

DB 테이블

test_table

id value
1 hoge
2 fuga
3 piyo

폴더 구성

├── build.gradle
├── src/main/
│   └── java/
│   └── sample/mybatis/springboot/
│       └── Main.java
│       └── TestTableMapper.java
└── resources/
    └── application.properties
    └── mybatis-config.xml
    └── TestTableMapper.xml

소스 코드

build.gradle

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath 'org.springframework.boot:spring-boot-gradle-plugin:1.3.1.RELEASE'
    }
}

apply plugin: 'java'
apply plugin: 'spring-boot'

sourceCompatibility = '1.8'
targetCompatibility = '1.8'
compileJava.options.encoding = 'UTF-8'

repositories {
    mavenCentral()
}

dependencies {
    compile 'org.springframework.boot:spring-boot-starter'
    // MyBatis의 SpringBoot 용 의존 라이브러리 파일을 포함한다.
    compile 'org.mybatis.spring.boot:mybatis-spring-boot-starter:1.0.0'
    compile 'mysql:mysql-connector-java:5.1.38'
}

application.properties

# MyBatis 설정 파일을 로드한다.
mybatis.config=mybatis-config.xml

# 데이터 소스 설정한다.
spring.datasource.url=jdbc:mysql://localhost/test
spring.datasource.username=test
spring.datasource.password=test
spring.datasource.driver-class-name=com.mysql.jdbc.Driver

mybatis-config.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
  PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
 <!-- 데이터 소스 관리는 Spring Boot에서 하기 때문에 여기에 작성하지 않는다. -->
  <mappers>
    <mapper resource="TestTableMapper.xml"/>
  </mappers>
</configuration>

TestTableMapper.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="sample.mybatis.springboot.TestTableMapper">

  <select id="selectTest" resultType="map">
    select * from test_table
  </select>
</mapper>

TestTableMapper.java

package sample.mybatis.springboot;

import java.util.List;
import java.util.Map;

public interface TestTableMapper {

    List<Map<String, Object>> selectTest();
}

Main.java

package sample.mybatis.springboot;

import java.io.IOException;

import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;

@SpringBootApplication
public class Main {

    public static void main(String[] args) throws IOException {
        try (ConfigurableApplicationContext ctx = SpringApplication.run(Main.class, args)) {
            Main m = ctx.getBean(Main.class);
            m.method();
        }
    }

    @Autowired
    private SqlSessionTemplate sqlSession;
    @Autowired
    private TestTableMapper mapper;

    public void method() throws IOException {
        System.out.println("[SqlSessionTemplate]");
        this.sqlSession
            .selectList("sample.mybatis.springboot.TestTableMapper.selectTest")
            .forEach(System.out::println);

        System.out.println("[TestTableMapper]");
        this.mapper
            .selectTest()
            .forEach(System.out::println);
    }
}

실행결과

[SqlSessionTemplate]
{id=1, value=hoge}
{id=2, value=fuga}
{id=3, value=piyo}

[TestTableMapper]
{id=1, value=hoge}
{id=2, value=fuga}
{id=3, value=piyo}

설명

  • Spring Boot에서 MyBatis를 사용하는 경우에는 mybatis-spring-boot-starter를 의존성에 추가한다.
  • 다음에는 Spring Boot 설정 파일 (application.properties)에서 mybatis.config라는 이름으로 MyBatis 설정 파일을 지정한다.
  • 데이터 소스는 Spring Boot에서 관리해 주기 때문에, Spring Boot의 설정에서 작성하고 MyBatis에서는 따로 작성하지 않는다.
  • SqlSession에 액세스하려면 SqlSessionTemplate을 @Autowired에 주입하면 된다.
    • SqlSessionTemplate의 API는 SqlSession과 같다.
    • SqlSession과 달리 thread가 안전적이기 때문에 다른 스레드나 DAO에서 사용해도 문제 없다.
  • Mapper 인터페이스를 정의를 해두면, @Autowired에 주입할 수 있다.
    • Spring에 스캔되는 위치에 인터페이스를 넣어 두어야 한다.
    • Main 클래스를 @MapperScan에서 어노테이션하면, 모든 패키지 Mapper 인터페이스를 검색할 수 있다 (예 : @MapperScan( "foo.bar")).
    • 이쪽도 thread로 안전한 인스턴스가 주입되기 때문에 다른 스레드나 DAO에서 사용하여도 무방하다.
최종 수정 : 2021-08-26