[Spring Boot] Kotlin + Gradle MyBatis 연동

2021. 11. 2. 11:20Spring Boot/Information

프로젝트 진행중 JPA 뿐 아니라 MyBatis를 연동해야 할 일이 생겼다.

먼저 내가 진행하고 있는 프로젝트에 대해서는 모듈은 아래와 같이 분리되어 있다.

  1. Spring Boot Application 만 담고 있는 모듈
  2. 실제 로직이 작성되어 있는 모듈
  3. Entity Model 을 담고 있는 모듈

여기서 MyBatis & JPA 는 2번 모듈에 추가를 진행해야한다.

JPA는 연동을 이미 해놨고, 이제 MyBatis 만 연동하면 된다.

 

1. MyBatis Mapper 가 들어갈 모듈(2번), Spring Boot Application 이 있는 모듈(1번) 에 아래와 같이 Gradle에 Dependency를 추가시켜주자.

1
implementation("org.mybatis.spring.boot:mybatis-spring-boot-starter:2.1.4")
cs

Spring Boot 에서 제공하고 있는 MyBatis Dependency다.

 

2. DataSourceConfiguration 파일에  @MapperScan Annotation 을 이용해서 Mapper 를 사용할 basePackage를 지정해주자.

1
2
3
4
5
6
7
8
9
10
11
12
13
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
    entityManagerFactoryRef = "...",
    transactionManagerRef = "...",
    basePackages = ["..."]
)
@EntityScan(basePackages = ["..."])
@ComponentScan(basePackages=["..."])
@MapperScan(basePackages = ["..."])
class DataSourceConfiguration {
    ...
}
cs

여기서 핵심은 10번째 Line이다.

@Mapper 를 사용할 패키지를 적용해주면 된다.

나같은 경우에는 2번 모듈의 패키지 명을 작성하였다.

 

3. applicaton.yml 파일에 MyBatis XML 이 작성될 경로를 작성해주자.

1
2
mybatis:
  mapper-locations: mybatis/**/*.xml
cs

2번 모듈 내 resources 폴더 → mybatis 폴더 → domain 명... 안에다가 작성할 것 이기 때문에 위와 같이 지정했다.

 

4. XML(SQL) 작성

1
2
3
4
5
6
7
8
9
<?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="your.package.domain.test.TestSqlMapper">
    <select id = "getAll" resultType = "your.package.model.TestDTO">
        SELECT * FROM SELECT_TABLE
    </select>
</mapper>
 
cs

여기서 중요한 라인은 4번 라인, 5번 라인이다.

4번 : namespace는 5번에서 나올 Interface Class 경로를 적어주면 된다.

5번 : 5번에서 나올 Interface Class 내에서 사용할 함수 명으로 적어주면 된다.

resultType 같은 경우는 쿼리의 결과값을 resultType으로 변환해서 받겠다고 적어놓은 것이다.

 

5. Interface 작성

1
2
3
4
5
@Mapper
interface TestSqlMapper {
    fun getAll(): List<TestDTO>
}
 
cs

1번 Line에 의해 해당 Interface Class가 Bean으로 등록되었고, 이 후 Controller / Service에서 불러와 사용하면 된다.

여기서 함수 명은 Mapper XML에 ID와 일치하게 작성해야 한다.

 

6. 사용

1
2
3
4
5
6
7
8
9
10
11
@RestController
@RequestMapping("/api/test")
@RequiredArgsConstructor
class PaymentController @Inject constructor(
    private val testSqlMapper: TestSqlMapper
) {
    @RequestMapping(value = ["/getAll"], method = [RequestMethod.GET])
    fun getAll(): List<TestDTO> {
        return testSqlMapper.getAll()
    }
}
cs

http://localhost:8080/api/test/getAll 로 GET 메소드를 호출하게 되면 자신이 적은 SQL의 결과값이 나올 것 이다.

하지만 사용시에는 Controller 에서 Mapper를 갖고오는 것이 아니라, Service 에서 Mapper를 갖고오고 Controller 에서는 Service 를 참조하는 것을 추천한다.

(Service Class 내 데이터 가공 후 Controller 는 Return 만 하는 구조)

 

참조 문서

[Kotlin] Springboot + Mybatis 사용법

[springboot] mapper 관련 파일을 찾지 못할 때