使用 Spring Boot Kotlin 在启动时将 Liquibase 设置为 运行 和 SQL 脚本
Getting Liquibase to run an SQL script on start up with SpringBoot Kotlin
我无法让 liquibase 在我的 SpringBoot Kotlin 应用程序中执行我的 sql 脚本。
这是我的 build.gradle.kts
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
id("org.springframework.boot") version "2.5.4"
id("io.spring.dependency-management") version "1.0.11.RELEASE"
kotlin("jvm") version "1.5.21"
kotlin("plugin.spring") version "1.5.21"
}
group = "com.johncooper"
version = "0.0.1-SNAPSHOT"
java.sourceCompatibility = JavaVersion.VERSION_11
repositories {
mavenCentral()
}
sourceSets.main {
java.srcDirs("src/main")
}
sourceSets.test {
java.srcDirs("src/test", "src/cucumber/kotlin", "src/cucumber")
}
dependencies {
implementation("org.springframework.boot:spring-boot-starter-data-r2dbc")
implementation("org.springframework.boot:spring-boot-starter-validation")
implementation("org.springframework.boot:spring-boot-starter-webflux")
implementation("com.fasterxml.jackson.module:jackson-module-kotlin")
implementation("io.projectreactor.kotlin:reactor-kotlin-extensions")
implementation("org.jetbrains.kotlin:kotlin-reflect")
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-reactor")
implementation("org.json:json:20211205")
implementation("com.fasterxml.jackson.module:jackson-module-kotlin")
implementation("org.springdoc:springdoc-openapi-webflux-ui:1.6.4")
implementation("org.springdoc:springdoc-openapi-kotlin:1.6.3")
implementation("org.mariadb:r2dbc-mariadb")
implementation("org.liquibase:liquibase-gradle-plugin:2.0.3")
implementation("org.liquibase:liquibase-core:2.0.3")
implementation("org.mariadb.jdbc:mariadb-java-client:3.0.3")
testImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-test")
testImplementation("org.junit.jupiter:junit-jupiter-engine")
testImplementation("org.testcontainers:testcontainers:1.16.0")
testImplementation("org.testcontainers:junit-jupiter:1.16.0")
testImplementation("org.testcontainers:mariadb:1.16.3")
testImplementation("org.testcontainers:r2dbc:1.16.0")
testImplementation("org.mockito.kotlin:mockito-kotlin:4.0.0")
testImplementation("org.springframework.boot:spring-boot-starter-test")
testImplementation("io.projectreactor:reactor-test")
testImplementation("org.junit.vintage:junit-vintage-engine:5.7.2")
testImplementation("io.cucumber:cucumber-java:6.11.0")
testImplementation("io.cucumber:cucumber-spring:6.11.0")
testImplementation("io.cucumber:cucumber-junit:6.11.0")
}
tasks.withType<KotlinCompile> {
kotlinOptions {
freeCompilerArgs = listOf("-Xjsr305=strict")
jvmTarget = "11"
}
}
tasks.withType<Test> {
useJUnitPlatform()
}
tasks {
test {
filter {
excludeTestsMatching("**.RunBDDTests")
}
}
}
task<Test>("acceptanceTest") {
useJUnitPlatform()
filter {
includeTestsMatching("**.RunBDDTests")
}
}
这是我的 application.properties -
server.port=9000
spring.r2dbc.url=r2dbc:mariadb://0.0.0.0:3306/mydb
spring.r2dbc.username=testuser
spring.r2dbc.password=mypwd
spring.r2dbc.initialization-mode= always
spring.liquibase.url=jdbc:mariadb://0.0.0.0:3306/mydb
spring.liquibase.user=testuser
spring.liquibase.password=mypwd
spring.liquibase.change-log=classpath:db/changelog/db.changelog-master.xml
spring.liquibase.enabled=true
logging.level.org.springframework.data.r2dbc=INFO
debug=false
logging.level.com.johncooper=INFO
这是我的 db.changelog-master.xml 位于 src/main/resources/db/changelog/ -
<databaseChangeLog
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.1.xsd">
<include file="data.sql" relativeToChangelogFile="true"/>
</databaseChangeLog>
这是我要执行的脚本 data.sql -
# liquibase formatted sql
# changeset mydb:data
DROP TABLE IF EXISTS pets;
CREATE TABLE pets (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(250) NOT NULL,
description VARCHAR(250) NOT NULL,
breed VARCHAR(250) NOT NULL,
type VARCHAR(250) NOT NULL,
price VARCHAR(250) NOT NULL
);
INSERT INTO pets (name, description, breed, type, price) VALUES
('Nemo', 'fish', 'piranah', 'a fricking fich', '0')
# rollback DROP TABLE IF EXISTS mydb.pets
通过 Intellij 运行应用程序 ./gradlew bootRun
没有错误。该脚本根本没有得到 运行。谁能发现我做错了什么?
更新 - 这是 link 到 github 代码库的 link 我的代码:https://github.com/johnnyalpha8/Pet-Shop
虽然 运行 在启用调试日志的情况下设置您的设置,但我注意到 Liquibase 的 auto-configuration 不起作用,因为未满足某些条件。
LiquibaseAutoConfiguration.LiquibaseConfiguration:
Did not match:
- @ConditionalOnClass did not find required class 'org.springframework.jdbc.core.ConnectionCallback' (OnClassCondition)
class org.springframework.jdbc.core.ConnectionCallback
作为 spring-boot-starter-data-jdbc
的一部分提供。
通过对您的 build.gradle.kts
进行以下调整,您的 .sql
文件将由 Liquibase 获取。
dependencies {
// - provides the missing class for auto-configuration
implementation("org.springframework.boot:spring-boot-starter-data-jdbc")
...
// - this dependency seems to be unnecessary
// implementation("org.liquibase:liquibase-gradle-plugin:2.0.3")
// - you provided an outdated version
// - a version must not be provided as it is managed by Spring Boot
implementation("org.liquibase:liquibase-core")
...
但是,您的 .sql
脚本包含语法错误。我不熟悉基于 .sql
文件的 Liquibase,但我使用 Liquibase 的 .xml
文件语法将其设置为 运行。
db.changelog-master.xml
<databaseChangeLog
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.1.xsd">
<include file="db.changelog-0001.xml" relativeToChangelogFile="true"/>
</databaseChangeLog>
db.changelog-0001.xml
<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLog
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.3.xsd">
<changeSet id="1" author="jalpha">
<createTable tableName="pets">
<column name="id" type="int" autoIncrement="true">
<constraints primaryKey="true" nullable="false"/>
</column>
<column name="name" type="varchar(250)">
<constraints nullable="false"/>
</column>
<column name="description" type="varchar(250)">
<constraints nullable="false"/>
</column>
<column name="breed" type="varchar(250)">
<constraints nullable="false"/>
</column>
<column name="type" type="varchar(250)">
<constraints nullable="false"/>
</column>
<column name="price" type="varchar(250)">
<constraints nullable="false"/>
</column>
</createTable>
<insert tableName="pets">
<column name="name" value="Nemo"/>
<column name="description" value="fish"/>
<column name="breed" value="piranah"/>
<column name="type" value="a fricking fich"/>
<column name="price" value="0"/>
</insert>
</changeSet>
</databaseChangeLog>
感谢您提供示例存储库,这极大地帮助了重现错误。
我无法让 liquibase 在我的 SpringBoot Kotlin 应用程序中执行我的 sql 脚本。
这是我的 build.gradle.kts
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
id("org.springframework.boot") version "2.5.4"
id("io.spring.dependency-management") version "1.0.11.RELEASE"
kotlin("jvm") version "1.5.21"
kotlin("plugin.spring") version "1.5.21"
}
group = "com.johncooper"
version = "0.0.1-SNAPSHOT"
java.sourceCompatibility = JavaVersion.VERSION_11
repositories {
mavenCentral()
}
sourceSets.main {
java.srcDirs("src/main")
}
sourceSets.test {
java.srcDirs("src/test", "src/cucumber/kotlin", "src/cucumber")
}
dependencies {
implementation("org.springframework.boot:spring-boot-starter-data-r2dbc")
implementation("org.springframework.boot:spring-boot-starter-validation")
implementation("org.springframework.boot:spring-boot-starter-webflux")
implementation("com.fasterxml.jackson.module:jackson-module-kotlin")
implementation("io.projectreactor.kotlin:reactor-kotlin-extensions")
implementation("org.jetbrains.kotlin:kotlin-reflect")
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-reactor")
implementation("org.json:json:20211205")
implementation("com.fasterxml.jackson.module:jackson-module-kotlin")
implementation("org.springdoc:springdoc-openapi-webflux-ui:1.6.4")
implementation("org.springdoc:springdoc-openapi-kotlin:1.6.3")
implementation("org.mariadb:r2dbc-mariadb")
implementation("org.liquibase:liquibase-gradle-plugin:2.0.3")
implementation("org.liquibase:liquibase-core:2.0.3")
implementation("org.mariadb.jdbc:mariadb-java-client:3.0.3")
testImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-test")
testImplementation("org.junit.jupiter:junit-jupiter-engine")
testImplementation("org.testcontainers:testcontainers:1.16.0")
testImplementation("org.testcontainers:junit-jupiter:1.16.0")
testImplementation("org.testcontainers:mariadb:1.16.3")
testImplementation("org.testcontainers:r2dbc:1.16.0")
testImplementation("org.mockito.kotlin:mockito-kotlin:4.0.0")
testImplementation("org.springframework.boot:spring-boot-starter-test")
testImplementation("io.projectreactor:reactor-test")
testImplementation("org.junit.vintage:junit-vintage-engine:5.7.2")
testImplementation("io.cucumber:cucumber-java:6.11.0")
testImplementation("io.cucumber:cucumber-spring:6.11.0")
testImplementation("io.cucumber:cucumber-junit:6.11.0")
}
tasks.withType<KotlinCompile> {
kotlinOptions {
freeCompilerArgs = listOf("-Xjsr305=strict")
jvmTarget = "11"
}
}
tasks.withType<Test> {
useJUnitPlatform()
}
tasks {
test {
filter {
excludeTestsMatching("**.RunBDDTests")
}
}
}
task<Test>("acceptanceTest") {
useJUnitPlatform()
filter {
includeTestsMatching("**.RunBDDTests")
}
}
这是我的 application.properties -
server.port=9000
spring.r2dbc.url=r2dbc:mariadb://0.0.0.0:3306/mydb
spring.r2dbc.username=testuser
spring.r2dbc.password=mypwd
spring.r2dbc.initialization-mode= always
spring.liquibase.url=jdbc:mariadb://0.0.0.0:3306/mydb
spring.liquibase.user=testuser
spring.liquibase.password=mypwd
spring.liquibase.change-log=classpath:db/changelog/db.changelog-master.xml
spring.liquibase.enabled=true
logging.level.org.springframework.data.r2dbc=INFO
debug=false
logging.level.com.johncooper=INFO
这是我的 db.changelog-master.xml 位于 src/main/resources/db/changelog/ -
<databaseChangeLog
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.1.xsd">
<include file="data.sql" relativeToChangelogFile="true"/>
</databaseChangeLog>
这是我要执行的脚本 data.sql -
# liquibase formatted sql
# changeset mydb:data
DROP TABLE IF EXISTS pets;
CREATE TABLE pets (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(250) NOT NULL,
description VARCHAR(250) NOT NULL,
breed VARCHAR(250) NOT NULL,
type VARCHAR(250) NOT NULL,
price VARCHAR(250) NOT NULL
);
INSERT INTO pets (name, description, breed, type, price) VALUES
('Nemo', 'fish', 'piranah', 'a fricking fich', '0')
# rollback DROP TABLE IF EXISTS mydb.pets
通过 Intellij 运行应用程序 ./gradlew bootRun
没有错误。该脚本根本没有得到 运行。谁能发现我做错了什么?
更新 - 这是 link 到 github 代码库的 link 我的代码:https://github.com/johnnyalpha8/Pet-Shop
虽然 运行 在启用调试日志的情况下设置您的设置,但我注意到 Liquibase 的 auto-configuration 不起作用,因为未满足某些条件。
LiquibaseAutoConfiguration.LiquibaseConfiguration:
Did not match:
- @ConditionalOnClass did not find required class 'org.springframework.jdbc.core.ConnectionCallback' (OnClassCondition)
class org.springframework.jdbc.core.ConnectionCallback
作为 spring-boot-starter-data-jdbc
的一部分提供。
通过对您的 build.gradle.kts
进行以下调整,您的 .sql
文件将由 Liquibase 获取。
dependencies {
// - provides the missing class for auto-configuration
implementation("org.springframework.boot:spring-boot-starter-data-jdbc")
...
// - this dependency seems to be unnecessary
// implementation("org.liquibase:liquibase-gradle-plugin:2.0.3")
// - you provided an outdated version
// - a version must not be provided as it is managed by Spring Boot
implementation("org.liquibase:liquibase-core")
...
但是,您的 .sql
脚本包含语法错误。我不熟悉基于 .sql
文件的 Liquibase,但我使用 Liquibase 的 .xml
文件语法将其设置为 运行。
db.changelog-master.xml
<databaseChangeLog
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.1.xsd">
<include file="db.changelog-0001.xml" relativeToChangelogFile="true"/>
</databaseChangeLog>
db.changelog-0001.xml
<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLog
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.3.xsd">
<changeSet id="1" author="jalpha">
<createTable tableName="pets">
<column name="id" type="int" autoIncrement="true">
<constraints primaryKey="true" nullable="false"/>
</column>
<column name="name" type="varchar(250)">
<constraints nullable="false"/>
</column>
<column name="description" type="varchar(250)">
<constraints nullable="false"/>
</column>
<column name="breed" type="varchar(250)">
<constraints nullable="false"/>
</column>
<column name="type" type="varchar(250)">
<constraints nullable="false"/>
</column>
<column name="price" type="varchar(250)">
<constraints nullable="false"/>
</column>
</createTable>
<insert tableName="pets">
<column name="name" value="Nemo"/>
<column name="description" value="fish"/>
<column name="breed" value="piranah"/>
<column name="type" value="a fricking fich"/>
<column name="price" value="0"/>
</insert>
</changeSet>
</databaseChangeLog>
感谢您提供示例存储库,这极大地帮助了重现错误。