SpringBoot 애플리케이션에서 mybatis를 사용하는 경우, 컴파일 타임 쿼리 검증을 위한 모듈 (gradle plugin) 입니다.
-
Java : 21+
-
Spring Boot : 3.2.x
- Boot 3.2.x plugin에서 수행하는 runner.jar 가 SpringBoot 3.2.5 버전 의존성을 사용합니다.
- Boot 2.x gradle - runner.jar 에 의존성이 모두 fat jar 로 포함되어있어, 별도 의존성 문제는 없습니다. maven - plugin을 직접 실행시키는 방식이 아니라, exec-maven-plugin 을 통해 실행시키는 방식이기에 Springboot 3.x 버전 의존성을 따릅니다. (AutoConfiguration imports 포함)
- settings.gradle
pluginManagement {
repositories {
maven {
url = uri("http://mavenpro.nmn.io/repository/Public-Repositories")
allowInsecureProtocol = true
}
gradlePluginPortal()
mavenCentral()
}
}- build.gradle
plugins {
id 'com.netmarble.mybatis-sql-validator' version '0.1.0'
}
mybatisSqlValidator {
imports = [
// 검증할 mybatis config class 명. EX)
"com.netmarble.identityverification.config.AuthUserDataSourceConfig"
]
}- pom.xml
<dependencies>
<dependency>
<groupId>com.netmarble.tools</groupId>
<artifactId>mybatis-sql-validator-runner</artifactId>
<version>0.1.0</version>
</dependency>
</dependencies>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>3.5.0</version>
<executions>
<execution>
<id>validate-mybatis-sql</id>
<phase>verify</phase>
<goals>
<goal>java</goal>
</goals>
<configuration>
<mainClass>
com.netmarble.tools.mybatisvalidator.runner.SqlValidateEntrypoint
</mainClass>
<systemProperties>
<systemProperty>
<key>validator.imports</key>
<value>
<!-- DataSource ConfigurationProperties AutoConfiguration을 위해 필수로 포함되어야하는 class 명 -->
org.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfiguration,
<!-- 검증할 mybatis config class 명. EX) -->
com.netmarble.crossplayplatformauth.infrastructure.mysql.DataSourceConfig
</value>
</systemProperty>
</systemProperties>
<classpathScope>runtime</classpathScope>
</configuration>
</execution>
</executions>
</plugin>-
위 의존성을 추가합니다.
-
Gradle, Maven sync 및 빌드를 진행합니다.
- gradle
./gradlew clean build- maven
./mvnw clean verify- 빌드 시점에 mybatis 쿼리 검증이 수행됩니다.
mybatis-sql-validator는 애플리케이션을 실제로 실행하지 않고,
빌드 시점에 Spring Context를 최소 구성으로 기동하여
MyBatis에 등록된 모든 SQL을 실제 DB 기준으로 사전 검증합니다.
- Spring Context를 headless 모드로 기동
- MyBatis SqlSessionFactory 수집
- 각 Factory에 등록된 MappedStatement 순회
- Dummy 파라미터 생성 → BoundSql 생성
- 실제 DB Connection 기준으로 prepare / explain 검증
- 검증 결과를 Valid / Skipped / Failed 로 분류
- Error 발생 시 빌드 실패
- 본 모듈은 일반적인 @SpringBootApplication 기반의 기동이 아닌,
- 검증에 필요한 설정 클래스만을 명시적으로 import 하여 Context를 기동합니다.
new SpringApplicationBuilder(sources)
.web(WebApplicationType.NONE)
.run(args);-
Context 기동 시 사용할 설정 클래스는 다음 우선순위로 결정됩니다.
-Dvalidator.bootstrapClass-Dvalidator.imports (separator=',')- 둘 다 없을 경우 -> 즉시 실패
-
Gradle Plugin 사용 시
검증 전용 Bootstrap Config가 자동 생성됩니다. -
Maven 사용 시
시스템 프로퍼티에 validator.imports 설정 클래스를 명시적으로 지정해야 합니다.
- 본 validator는
@ConfigurationProperties기반의DataSource/HikariConfig바인딩을 지원하기 위해
ConfigurationPropertiesAutoConfiguration을 반드시 명시적으로 import 해야 합니다.
(해당 AutoConfiguration이 누락될 경우 DataSource 바인딩이 정상적으로 동작하지 않습니다.)
-
검증의 기준 단위는
DataSource가 아닌 MyBatisSqlSessionFactory입니다.- 하나의 DataSource에 여러 SqlSessionFactory가 연결될 수 있음
- Factory 단위로 서로 다른 Mapper / Configuration을 가질 수 있음
- 실제 SQL 등록 단위는 SqlSessionFactory -> Configuration -> MappedStatement
-
따라서 다음 순서로 검증이 수행됩니다.
SqlSessionFactory
└─ Configuration
└─ MappedStatement (select / insert / update / delete)
-
각 MappedStatement에 대해 다음 절차로 SQL을 재구성합니다.
- Mapper interface 메서드 시그니처 기반 parameter seed 생성
- 기본 primitive type에 대한 dummy 값 자동 생성
- foreach 관례 키 (list, collection, array) 기본 주입
- ParameterMapping 기준 누락 파라미터 보완
- MappedStatement#getBoundSql(param) 호출
-
이 과정에서 예외가 발생할 경우 해당 SQL은 Skipped 처리됩니다.
-
BoundSql 생성이 완료되면, DB 타입(MySQL / MsSQL 등)에 맞는 Validation Strategy가 선택되어 다음 검증이 수행됩니다.
PreparedStatement생성SQL 문법검증테이블 / 컬럼 존재 여부검증- EXPLAIN 기반 실행 가능성 확인
-
이 단계에서 발생한 SQLException은 Failed 처리됩니다.