如何使用Gradle、Testcontainers和Flyway配置jOOQ?

vfh0ocws  于 2023-02-09  发布在  其他
关注(0)|答案(2)|浏览(161)

我需要配置gradle构建文件的jOOQ与Testcontainers和Flyway的示例,在jOOQ的官方存储库中,我只找到maven示例,无法将其转换为gradle,我尝试自己转换,但得到了这个:

buildscript {
    repositories {
        mavenLocal()
        mavenCentral()
    }
    dependencies { 
        // test container
        classpath "org.testcontainers:postgresql:$testContainersVersion"
    }
}

plugins {
    id 'java'
    id 'nu.studer.jooq' version "$jooqPluginVersion"
    id "org.flywaydb.flyway" version "$flywayPluginVersion"
}

repositories {
    mavenLocal()
    mavenCentral()
}

dependencies {
    // spring
    implementation 'org.springframework.boot:spring-boot-starter'
    implementation 'org.springframework.boot:spring-boot-starter-jooq'

    // postgres
    runtimeOnly 'org.postgresql:postgresql'

    // jooq
    jooqGenerator "org.postgresql:postgresql:$postgresVersion"

    // flyway
    implementation 'org.flywaydb:flyway-core'

    // tests
    testImplementation "org.junit.jupiter:junit-jupiter-api:$junitVersion"
    testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:$junitVersion"
    testImplementation "org.testcontainers:testcontainers:$testContainersVersion"
    testImplementation "org.testcontainers:postgresql:$testContainersVersion"
}
var JdbcDatabaseContainer<?> postgres = new PostgreSQLContainerProvider().newInstance("14-alpine")
postgres.start()

flyway {
    url = postgres.jdbcUrl
    user = postgres.username
    password = postgres.password
    schemas = ['public']
    locations = ['classpath:db/migration']
    baselineOnMigrate = true
}
tasks { 
    doLast {
        if (postgres.isRunning) {
            println("STOPPING DATABASE CONTAINER")
            postgres.stop()
        }
    }
}

jooq {
    version = "$jookVersion"  // default (can be omitted)
    edition = JooqEdition.OSS  // default (can be omitted)

    configurations {
        main {  // name of the jOOQ configuration
            generateSchemaSourceOnCompilation = true  // default (can be omitted)

            generationTool {
                logging = org.jooq.meta.jaxb.Logging.WARN
                jdbc {
                    driver = 'org.postgresql.Driver'
                    url = postgres.jdbcUrl
                    user = postgres.username
                    password = postgres.password
                }
                generator {
                    name = 'org.jooq.codegen.DefaultGenerator'
                    database {
                        name = 'org.jooq.meta.postgres.PostgresDatabase'
                        inputSchema = 'public'
                        forcedTypes {
                            forcedType {
                                userType = 'com.fasterxml.jackson.databind.JsonNode'
                                includeTypes = '.*'
                                includeExpression = '.*JSON.*'
                                binding = 'dataflow.binding.PostgresJSONBBinding'
                            }
                        }
                    }
                    generate {
                        pojosAsKotlinDataClasses = true
                        deprecated = false
                        records = true
                        pojos = true
                        immutablePojos = false
                        fluentSetters = true
                        daos = true
                    }
                    target {
                        packageName = "dataflow.$dataflowPackageName"
                        directory = 'build/generated-src/jooq/main'  // default (can be omitted)
                    }
                    strategy.name = 'org.jooq.codegen.DefaultGeneratorStrategy'
                }
            }
        }
    }
}

它创建了三个容器,而不是一个,并且不停止它们。另外,我使用Gradle jOOQ plugin

4si2a6ki

4si2a6ki1#

我最近遇到了类似的mysql,gradle,flyway和jooq的案例。基于gradle-jooq-plugin(https://github.com/etiennestuder/gradle-jooq-plugin/blob/master/example/)的例子,我为我的案例提出了可行的解决方案,只需稍作修改,它也应该适用于您的案例:

import org.testcontainers.containers.MySQLContainer

buildscript {
    repositories {
        mavenLocal()
        mavenCentral()
    }
    dependencies {
        classpath 'org.testcontainers:mysql:1.17.3'
        classpath 'mysql:mysql-connector-java:8.0.29'
        classpath 'org.flywaydb:flyway-mysql:9.0.1'

    }
}

plugins {
    id 'java'
    id 'org.flywaydb.flyway' version '9.0.1'
    id 'nu.studer.jooq' version '7.1.1'
}

repositories {
    mavenLocal()
    mavenCentral()
}

configurations {
    flywayMigration
}

dependencies {
    jooqGenerator('mysql:mysql-connector-java:8.0.29')
}

task mysqlContainer {
    var instance = new MySQLContainer("mysql:8.0.29")
            .withDatabaseName('example')
    instance.start()
    mysqlContainer.ext.jdbcUrl = instance.getJdbcUrl()
    mysqlContainer.ext.username = instance.getUsername()
    mysqlContainer.ext.password = instance.getPassword()
    mysqlContainer.ext.databaseName = instance.getDatabaseName()
    mysqlContainer.ext.instance = instance
}

flyway {
    locations = ['filesystem:./src/main/resources/db/migration']
    configurations = ['flywayMigration']
    url = mysqlContainer.jdbcUrl
    user = mysqlContainer.username
    password = mysqlContainer.password
}

jooq {
    configurations {
        main {
            generationTool {
                logging = org.jooq.meta.jaxb.Logging.WARN
                jdbc {
                    driver = 'com.mysql.cj.jdbc.Driver'
                    url = mysqlContainer.jdbcUrl
                    user =mysqlContainer.username
                    password = mysqlContainer.password
                }
                generator {
                    name = 'org.jooq.codegen.DefaultGenerator'
                    database {
                        name = 'org.jooq.meta.mysql.MySQLDatabase'
                        includes = '.*'
                        inputSchema = mysqlContainer.databaseName
                        outputSchemaToDefault = true
                    }
                    target {
                        packageName = 'com.example.jooq'
                    }
                }
            }
        }
    }
}

tasks.named('generateJooq').configure {
    dependsOn tasks.named('mysqlContainer')
    dependsOn tasks.named('flywayMigrate')

    inputs.files(fileTree('src/main/resources/db/migration'))
            .withPropertyName('migrations')
            .withPathSensitivity(PathSensitivity.RELATIVE)

    allInputsDeclared = true
    doLast {
        mysqlContainer.instance.stop()
    }
}
fykwrbwg

fykwrbwg2#

我们使用下面的流程(它是Kotlin,只包含脚本中与JOOQ资源相关的部分)。与this answer的主要区别是,我的流程在你只运行generateJooq任务时会启动一个新容器。另一个流程在每个任务中都会运行一个新容器。

...

val containerInstance: PostgreSQLContainer<Nothing>? = if ("generateJooq" in project.gradle.startParameter.taskNames) {
    PostgreSQLContainer<Nothing>(
        DockerImageName.parse(
            "postgres:14.4-alpine",
        ),
    ).apply {
        withDatabaseName("my-db")
        start()
    }
} else {
    null
}

flyway {
    url = containerInstance?.jdbcUrl
    user = containerInstance?.username
    password = containerInstance?.password
}

jooq {
    version.set("3.17.5") // default (can be omitted)
    edition.set(nu.studer.gradle.jooq.JooqEdition.OSS) // default (can be omitted)

    configurations {
        create("main") { // name of the jOOQ configuration
            generateSchemaSourceOnCompilation.set(false) // default (can be omitted)
            jooqConfiguration.apply {
                logging = Logging.ERROR
                jdbc.apply {
                    driver = "org.postgresql.Driver"
                    url = containerInstance?.jdbcUrl
                    user = containerInstance?.username
                    password = containerInstance?.password
                }
                generator.apply {
                    name = "org.jooq.codegen.DefaultGenerator"
                    database.apply {
                        name = "org.jooq.meta.postgres.PostgresDatabase"
                        inputSchema = "public"
                        isIncludeIndexes = false
                        excludes = "flyway.*"
                    }
                    target.apply {
                        packageName = "mypackage"
                        directory = "src/main/java"
                    }
                    strategy.name = "org.jooq.codegen.DefaultGeneratorStrategy"
                }
            }
        }
    }
}

// This validation is optional. In our flow, we use flyway migrate plugin in only jooq resources generation flow
tasks.flywayMigrate.configure {
    val taskNames = project.gradle.startParameter.taskNames
    if ("flyMigrate" in taskNames && "generateJooq" !in taskNames) {
        throw IllegalArgumentException("Flyway migrate is only available for generateJooq task")
    }
}

tasks.named("generateJooq").configure {
    dependsOn(tasks.named("flywayMigrate"))
    doLast {
        containerInstance?.stop()
    }
}

...

相关问题