Skip to content

Repository files navigation

mybatis-sql-validator

SpringBoot 애플리케이션에서 mybatis를 사용하는 경우, 컴파일 타임 쿼리 검증을 위한 모듈 (gradle plugin) 입니다.


호환성 (Test-completed)

  • 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 포함)

설치

[Gradle plugin]

  • 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"
    ]
}

[Maven]

  • 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>

빠른 시작 (서비스 적용 관점)

  1. 위 의존성을 추가합니다.

  2. Gradle, Maven sync 및 빌드를 진행합니다.

  • gradle
./gradlew clean build
  • maven
./mvnw clean verify
  1. 빌드 시점에 mybatis 쿼리 검증이 수행됩니다.

동작 방식

mybatis-sql-validator는 애플리케이션을 실제로 실행하지 않고,
빌드 시점에 Spring Context를 최소 구성으로 기동하여
MyBatis에 등록된 모든 SQL을 실제 DB 기준으로 사전 검증합니다.

전체 흐름 요약

  1. Spring Context를 headless 모드로 기동
  2. MyBatis SqlSessionFactory 수집
  3. 각 Factory에 등록된 MappedStatement 순회
  4. Dummy 파라미터 생성 → BoundSql 생성
  5. 실제 DB Connection 기준으로 prepare / explain 검증
  6. 검증 결과를 Valid / Skipped / Failed 로 분류
  7. Error 발생 시 빌드 실패

세부 동작 방식

1. Spring Context 기동 방식

  • 본 모듈은 일반적인 @SpringBootApplication 기반의 기동이 아닌,
  • 검증에 필요한 설정 클래스만을 명시적으로 import 하여 Context를 기동합니다.
new SpringApplicationBuilder(sources)
    .web(WebApplicationType.NONE)
    .run(args);

2. Bootstrap Config 로딩 전략

  • Context 기동 시 사용할 설정 클래스는 다음 우선순위로 결정됩니다.

    1. -Dvalidator.bootstrapClass
    2. -Dvalidator.imports (separator=',')
    3. 둘 다 없을 경우 -> 즉시 실패
  • Gradle Plugin 사용 시
    검증 전용 Bootstrap Config가 자동 생성됩니다.

  • Maven 사용 시
    시스템 프로퍼티에 validator.imports 설정 클래스를 명시적으로 지정해야 합니다.

3. ConfigurationProperties AutoConfiguration

  • 본 validator는 @ConfigurationProperties 기반의 DataSource / HikariConfig 바인딩을 지원하기 위해
    ConfigurationPropertiesAutoConfiguration 을 반드시 명시적으로 import 해야 합니다.
    (해당 AutoConfiguration이 누락될 경우 DataSource 바인딩이 정상적으로 동작하지 않습니다.)

4. SqlSessionFactory 기반 검증 단위

  • 검증의 기준 단위는 DataSource 가 아닌 MyBatis SqlSessionFactory 입니다.

    • 하나의 DataSource에 여러 SqlSessionFactory가 연결될 수 있음
    • Factory 단위로 서로 다른 Mapper / Configuration을 가질 수 있음
    • 실제 SQL 등록 단위는 SqlSessionFactory -> Configuration -> MappedStatement
  • 따라서 다음 순서로 검증이 수행됩니다.

SqlSessionFactory
 └─ Configuration
     └─ MappedStatement (select / insert / update / delete)

5. Dummy Parameter & BoundSql 생성

  • 각 MappedStatement에 대해 다음 절차로 SQL을 재구성합니다.

    1. Mapper interface 메서드 시그니처 기반 parameter seed 생성
    2. 기본 primitive type에 대한 dummy 값 자동 생성
    3. foreach 관례 키 (list, collection, array) 기본 주입
    4. ParameterMapping 기준 누락 파라미터 보완
    5. MappedStatement#getBoundSql(param) 호출
  • 이 과정에서 예외가 발생할 경우 해당 SQL은 Skipped 처리됩니다.

6. 실제 SQL 검증 (prepare / explain)

  • BoundSql 생성이 완료되면, DB 타입(MySQL / MsSQL 등)에 맞는 Validation Strategy가 선택되어 다음 검증이 수행됩니다.

    • PreparedStatement 생성
    • SQL 문법 검증
    • 테이블 / 컬럼 존재 여부 검증
    • EXPLAIN 기반 실행 가능성 확인
  • 이 단계에서 발생한 SQLException은 Failed 처리됩니다.

About

No description, website, or topics provided.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages