πŸ‡¬πŸ‡§ Read in English: Quick Start: Spring Boot Web with Exposed

κ°œμš”

Kotlin Exposed 의 μ„ΈλΆ€ λ‚΄μš©μ„ κ³΅λΆ€ν•˜κΈ° 전에 κ°„λ‹¨ν•œ 예제λ₯Ό 톡해 Exposed λ₯Ό μ–΄λ–»κ²Œ μ‚¬μš©ν•  수 μžˆλŠ”μ§€ μ•Œμ•„λ΄…μ‹œλ‹€.

Kotlin Exposed λŠ” 자체 transaction ν•¨μˆ˜ 뿐 μ•„λ‹ˆλΌ Spring Framework의 Transactionκ³Ό μžμ—°μŠ€λŸ½κ²Œ 톡합될 수 μžˆλ„λ‘ @Transactional 을 μ§€μ›ν•©λ‹ˆλ‹€. 이λ₯Ό ν™œμš©ν•˜λ©΄, μ•„μ£Ό μ‰½κ²Œ spring-data-jpa λ₯Ό μ‚¬μš©ν•˜λŠ” 것과 μœ μ‚¬ν•˜κ²Œ μ–΄ν”Œλ¦¬μΌ€μ΄μ…˜μ„ μ œμž‘ν•  수 있고, 더 쒋은 μ„±λŠ₯을 κ°–μΆœ 수 μžˆμŠ΅λ‹ˆλ‹€.

특히 Java 21 의 Virtual Threads λ₯Ό μ΄μš©ν•˜λŠ” κ²½μš°μ—λ„ 두 κ°€μ§€ λͺ¨λ‘ μ‚¬μš©μ΄ κ°€λŠ₯ν•©λ‹ˆλ‹€.

Entity 관계

이 μ˜ˆμ œμ—λŠ” μ˜ν™”μ™€ 배우 정보λ₯Ό κ΄€λ¦¬ν•˜λŠ” μ„œλΉ„μŠ€λ₯Ό μ œμž‘ν•˜λ €κ³  ν•©λ‹ˆλ‹€. ERD λ₯Ό λ³΄μ‹œλ©΄ μ˜ν™” 정보λ₯Ό λ‚˜νƒ€λ‚΄λŠ” movies ν…Œμ΄λΈ”κ³Ό 배우 정보λ₯Ό λ‚˜νƒ€λ‚΄λŠ” actors ν…Œμ΄λΈ”μ„ μ •μ˜ν•˜κ³ , μ˜ν™” μΆœμ—° 관계λ₯Ό λ‚˜νƒ€λ‚΄λŠ” actors_in_movies λΌλŠ” many-to-many ν˜•νƒœμ˜ λ§€ν•‘ ν…Œμ΄λΈ”μ„ μ •μ˜ν•©λ‹ˆλ‹€.

μ˜ν™”, 배우의 μΆœμ—° λ˜λŠ” ν”„λ‘œλ“€μ‹± 관계λ₯Ό λ‚˜νƒ€λ‚΄λŠ” ERD

μ˜ν™”, 배우의 μΆœμ—° λ˜λŠ” ν”„λ‘œλ“€μ‹± 관계λ₯Ό λ‚˜νƒ€λ‚΄λŠ” ERD

이번 μ˜ˆμ œλŠ” spring-mvc-exposed λΌλŠ” ν”„λ‘œμ νŠΈλ₯Ό 기반으둜 μ„€λͺ…ν•©λ‹ˆλ‹€.

exposed-workshop/01-spring-boot/spring-mvc-exposed at main Β· bluetape4k/exposed-workshop

ν™˜κ²½ μ„€μ •

예제 ν”„λ‘œμ νŠΈλŠ” λ‹€μŒκ³Ό 같은 ꡬ쑰λ₯Ό κ°€μ§‘λ‹ˆλ‹€. 일반적인 REST API μ„œλΉ„μŠ€μ˜ Spring MVC ꡬ쑰이며, 이번 μ˜ˆμ œμ—λŠ” Java 21 의 Virtual Threads λ₯Ό 지원할 수 μžˆλ„λ‘ ν•©λ‹ˆλ‹€.

ν”„λ‘œμ νŠΈ ꡬ쑰

ν”„λ‘œμ νŠΈ ꡬ쑰

이 μ˜ˆμ œλŠ” λ‹€μŒκ³Ό 같은 build.gradle.kts 둜 μ°Έμ‘°λ₯Ό μ •μ˜ν•©λ‹ˆλ‹€.

plugins {
    kotlin("plugin.spring")
    id(Plugins.spring_boot)
    id(Plugins.gatling) version Plugins.Versions.gatling  // μ„±λŠ₯ 츑정을 μˆ˜ν–‰ν•˜λŠ” Gatling 
}

springBoot {
    mainClass.set("exposed.workshop.springmvc.SpringMvcApplicationKt")

    buildInfo {
        properties {
            additional.put("name", "Spring MVC with Exposed")
            additional.put("java.version", JavaVersion.current())
        }
    }
}

@Suppress("UnstableApiUsage")
configurations {
    testImplementation.get().extendsFrom(compileOnly.get(), runtimeOnly.get())
}

dependencies {
    testImplementation(project(":exposed-shared-tests"))

    // bluetape4k
    implementation(Libs.bluetape4k_io)
    implementation(Libs.bluetape4k_jdbc)
    testImplementation(Libs.bluetape4k_spring_tests)

    // Exposed
    implementation(Libs.bluetape4k_exposed)
    implementation(Libs.exposed_core)
    implementation(Libs.exposed_jdbc)
    implementation(Libs.exposed_dao)
    implementation(Libs.exposed_java_time)
    implementation(Libs.exposed_spring_boot_starter)

    // Database Drivers
    implementation(Libs.hikaricp)

    // H2
    implementation(Libs.h2_v2)

    // MySQL
    implementation(Libs.bluetape4k_testcontainers)
    implementation(Libs.testcontainers_mysql)
    implementation(Libs.mysql_connector_j)

    // PostgreSQL
    implementation(Libs.bluetape4k_testcontainers)
    implementation(Libs.testcontainers_postgresql)
    implementation(Libs.postgresql_driver)

    // Spring Boot
    implementation(Libs.springBoot("autoconfigure"))
    annotationProcessor(Libs.springBoot("autoconfigure-processor"))
    annotationProcessor(Libs.springBoot("configuration-processor"))
    runtimeOnly(Libs.springBoot("devtools"))

    implementation(Libs.springBootStarter("web"))
    implementation(Libs.springBootStarter("aop"))
    implementation(Libs.springBootStarter("actuator"))
    implementation(Libs.springBootStarter("validation"))

    testImplementation(Libs.bluetape4k_spring_tests)
    testImplementation(Libs.springBootStarter("test")) {
        exclude(group = "junit", module = "junit")
        exclude(group = "org.junit.vintage", module = "junit-vintage-engine")
        exclude(module = "mockito-core")
    }

    // Others
}

build.gradle.kts μ—μ„œ bluetape4k-exposed λΌλŠ” μ œκ°€ μ œμž‘ν•œ 라이브러리λ₯Ό μ‚¬μš©ν•˜λŠ”λ°, 이 뢀뢄은 bluetape4k μ†Œκ°œ 및 ν™œμš© 방법 μ—μ„œ μžμ„Ένžˆ μ„€λͺ…ν•˜κ² μŠ΅λ‹ˆλ‹€.

이 ν”„λ‘œμ νŠΈμ—μ„œλŠ” SQL DSL (Domain Specific Language) 을 주둜 μ‚¬μš©ν•  μ˜ˆμ •μ΄λΌ exposed-jdbc λͺ¨λ“ˆμ„ 주둜 μ‚¬μš© 것이고, spring boot application 을 λ§Œλ“€κΈ° μœ„ν•΄μ„œ exposed-spring-boot-starter λͺ¨λ“ˆμ„ ν•„μˆ˜λ‘œ μ°Έμ‘°ν•΄μ•Ό ν•©λ‹ˆλ‹€.