강의

멘토링

커뮤니티

Cộng đồng Hỏi & Đáp của Inflearn

Hình ảnh hồ sơ của ikeelee4778
ikeelee4778

câu hỏi đã được viết

JOOQ ngoài đời thực! Gõ SQL an toàn với Java

Tạo dữ liệu thông qua câu lệnh chèn

generate dao 를 통한 삽입 시 pk auto-increment 가 적용되지 않습니다

Đã giải quyết

Viết

·

90

·

Đã chỉnh sửa

1

Kotlin, Groovy gradle, PostrgreSQL 기반으로 프로젝트 세팅이 되어 있습니다

 

@Repository
class ActorRepository(
    private val dsl: DSLContext,
    configuration: Configuration
) {
    private val actorDao = ActorDao(configuration)

    companion object {
        private val ACTOR = JActor.ACTOR
    }

    fun save(actor: Actor): Unit = actorDao.insert(actor)

}

이러한 방식으로 Repository 가 구현되어 있을 때,

 

@SpringBootTest
class ActorRepositoryTest(
    private val actorRepository: ActorRepository,
): StringSpec({

    "insert test" {
        val actor = Actor().apply {
            firstName = "John"
            lastName = "Doe"
        }

        println("Actor before insert: $actor")

        val insertedActor = actorRepository.save(actor)
    }

}) {
    override fun extensions() = listOf(SpringExtension)
}

 

image.pngimage.png

위 쿼리가 실행됩니다

제가 예상했던 insert into "actor" ("first_name", "last_name") values(?, ?) 과는 다르게 id 값이 0으로 고정되어 생성되더라구요

generate dao 를 생성하는 방법이 잘못된 걸까요?

sqlspring-bootjooqdslkotlin

Câu trả lời 1

2

sdm32851630님의 프로필 이미지
sdm32851630
Người chia sẻ kiến thức

이강현님 안녕하세요. 저도 궁금해서 로컬에서 코틀린으로 테스트해봤는데요.

코틀린의 경우, 로그에서만 auto increment 컬럼이 0으로 찍히고 정상적으로 동작하는것으로 보입니다. (신기하네요..?)

 

스크린샷 2025-08-09 오후 3.24.05.png.webp

 

참고로 kotlin으로 jOOQ를 사용하는 경우

코틀린 전용 generator를 사용하셔야합니다.

 

아래 링크 참고 부탁드립니다.

https://www.jooq.org/doc/latest/manual/code-generation/codegen-output-languages/kotlingenerator/

 

아래는 제가 테스트했을때 사용한 build.gradle 설정입니다.

('섹션 5. jOOQ 고급 - 다양한 방식으로 jOOQ DSL 만들기'에 있는 testcontainer + flyway 설정을 변형해서 사용했습니다.)

 

import org.jooq.meta.jaxb.*

buildscript {
    ext {
        jooqVersion = '3.19.5'
    }
}

plugins {
    id 'java'
    id 'org.springframework.boot' version '3.2.3'
    id 'io.spring.dependency-management' version '1.1.4'
    id 'dev.monosoul.jooq-docker' version '6.0.14'
    id "org.jetbrains.kotlin.jvm" version "1.9.24"
    id "org.jetbrains.kotlin.plugin.spring" version "1.9.24"
}

group = 'org.sight'
version = '0.0.1-SNAPSHOT'

java {
}

repositories {
    mavenCentral()
}

sourceSets {
    main {
        java {
            srcDirs = ["src/main/java", "src/generated"]
        }
    }
}


jooq {
    version = "${jooqVersion}"
    withContainer {
        image {
            name = "mysql:8.0.29"
            envVars = [
                    MYSQL_ROOT_PASSWORD: "passwd",
                    MYSQL_DATABASE     : "sakila"
            ]
        }

        db {
            username = "root"
            password = "passwd"
            name = "sakila"
            port = 3306
            jdbc {
                schema = "jdbc:mysql"
                driverClassName = "com.mysql.cj.jdbc.Driver"
            }
        }
    }
}

tasks {
    generateJooqClasses {
        schemas.set(["sakila"])
        outputDirectory.set(project.layout.projectDirectory.dir("src/generated"))
        includeFlywayTable.set(false)

        usingJavaConfig {
            withName('org.jooq.codegen.KotlinGenerator')
            generate = new Generate()
                    .withJavaTimeTypes(true)
                    .withDeprecated(false)
                    .withDaos(true)
                    .withFluentSetters(true)
                    .withRecords(true)
                    .withKotlinNotNullPojoAttributes(true) // NOT NULL 컬럼은 Kotlin의 Non-Null 타입으로 생성 (PK 제외)
                    .withKotlinNotNullRecordAttributes(true) // NOT NULL 컬럼은 Kotlin의 Non-Null 타입으로 생성 (PK 제외)

            withStrategy(
                    new Strategy().withName("jooq.custom.generator.JPrefixGeneratorStrategy")
            )

            database.withForcedTypes(
                    new ForcedType()
                            .withUserType("java.lang.Long")
                            .withTypes("int unsigned"),
                    new ForcedType()
                            .withUserType("java.lang.Integer")
                            .withTypes("tinyint unsigned"),
                    new ForcedType()
                            .withUserType("java.lang.Integer")
                            .withTypes("smallint unsigned")
            )
        }
    }
}

dependencies {
    implementation "org.jooq:jooq:${jooqVersion}"

    implementation 'org.springframework.boot:spring-boot-starter'
    implementation('org.springframework.boot:spring-boot-starter-jooq') {
        exclude group: 'org.jooq'
    }

    runtimeOnly 'com.mysql:mysql-connector-j'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
    compileOnly 'org.projectlombok:lombok'
    annotationProcessor 'org.projectlombok:lombok'

    testCompileOnly 'org.projectlombok:lombok'
    testAnnotationProcessor 'org.projectlombok:lombok'

    jooqCodegen project(':jooq-custom')
    jooqCodegen "org.jooq:jooq:${jooqVersion}"
    jooqCodegen "org.jooq:jooq-meta:${jooqVersion}"
    jooqCodegen "org.jooq:jooq-codegen:${jooqVersion}"

    jooqCodegen 'org.flywaydb:flyway-core:10.8.1'
    jooqCodegen 'org.flywaydb:flyway-mysql:10.8.1'
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8"
}

tasks.named('test') {
    useJUnitPlatform()
}
kotlin {
    jvmToolchain(17)
}
Hình ảnh hồ sơ của ikeelee4778
ikeelee4778

câu hỏi đã được viết

Đặt câu hỏi