无法从Liquibase Gradle插件生成差异

13

我正在尝试在已有的SpringBoot项目中使用liquibase和MYSQL数据库。我想要生成变更集,以便在实体更改时指定差异。

我的做法:

我在build.gradle文件中添加了liquibase依赖项和gradle liquibase插件。在进行领域更改后,我运行了gradle generateChangeLog。该命令成功执行,但什么也没有发生。

我在某个地方读到,这个gradle插件只适用于内存中的h2数据库?这是真的吗?如果是,那么我应该使用什么替代品来自动生成变更日志。

我找不到一个使用MYSQL并已经实现了liquibase与自动更改生成能力的工作示例。如果有人能提供这样的示例,那就太好了。

参考文献:

https://github.com/stevesaliman/liquibase-workshop

https://github.com/liquibase/liquibase-gradle-plugin

5个回答

27
解决方案是编写一个Gradle任务来调用liquibase diffChangeLog
在项目根目录中创建一个名为liquibase.gradle的文件,添加liquibase-hibernate扩展,并编写一个Gradle任务来调用liquibase diffChangeLog命令。
configurations {
  liquibase
}

dependencies {
  liquibase group: 'org.liquibase.ext', name: 'liquibase-hibernate4', version: 3.5
}

//loading properties file.
Properties liquibaseProps = new Properties()
liquibaseProps.load(new FileInputStream("src/main/resources/liquibase-task.properties"))

Properties applicationProps = new Properties()
applicationProps.load(new FileInputStream("src/main/resources/application.properties"))

task liquibaseDiffChangelog(type: JavaExec) {
  group = "liquibase"


  classpath sourceSets.main.runtimeClasspath
  classpath configurations.liquibase
  main = "liquibase.integration.commandline.Main"

  args "--changeLogFile=" + liquibaseProps.getProperty('liquibase.changelog.path')+ buildTimestamp() +"_changelog.xml"
  args "--referenceUrl=hibernate:spring:" + liquibaseProps.getProperty('liquibase.domain.package') + "?dialect=" + applicationProps.getProperty('spring.jpa.properties.hibernate.dialect')
  args "--username=" + applicationProps.getProperty('spring.datasource.username')
  args "--password=" + applicationProps.getProperty('spring.datasource.password')
  args "--url=" + applicationProps.getProperty('spring.datasource.url')
  args "--driver=com.mysql.jdbc.Driver"
  args "diffChangeLog"
}

def buildTimestamp() {
  def date = new Date()
  def formattedDate = date.format('yyyyMMddHHmmss')
  return formattedDate
}

注意:我使用属性文件将参数传递给liquibase命令,你也可以直接添加值,但这不是一个好的实践。

接下来,你需要在项目的build.gradle文件中应用liquibase.gradle文件,并添加liquibase依赖。

apply from: 'liquibase.gradle'
//code omitted
dependencies {
    compile (group: 'org.liquibase', name: 'liquibase-core', version: "3.4.2")
}

完成这个步骤后,Liquibase 就会完全设置好了。

现在你可以使用 gradle liquibaseDiffChangeLog 来生成变更日志。


5
在类型为org.gradle.api.internal.artifacts.dsl.dependencies.DefaultDependencyHandler的对象上,找不到方法liquibase(),其参数为[{group=org.liquibase.ext, name=liquibase-hibernate4, version=3.5}]。这种错误可以被解决,但该怎么做呢? - Vikrant Kashyap
1
请查看上面的评论。我相信你的解决方案会起作用,但我无法确定为什么会出现这个问题(我对gradle非常陌生)。我正在使用gradle版本4.1。谢谢 :) - Vikrant Kashyap
1
@VikrantKashyap,你解决了上述错误吗?如果是的话,能否分享解决方法,因为我也遇到了同样的错误。谢谢。 - Antony Vimal Raj
@VikrantKashyap,请问您能分享一下Maven项目的解决方案吗? - thiagolsilva

6

使用下面的设置,可以与liquibase-hibernateliquibase-gradle扩展一起使用:

plugins {
    id 'org.liquibase.gradle' version '2.0.1'
}

dependencies {
    implementation 'org.liquibase:liquibase-core:3.8.0'

    liquibaseRuntime 'org.liquibase.ext:liquibase-hibernate5:3.8'
    liquibaseRuntime sourceSets.main.runtimeClasspath
    liquibaseRuntime sourceSets.main.output
}

def props = new Properties()
file("src/main/resources/liquibase.properties").withInputStream { props.load(it) }

diff.dependsOn assemble
diffChangeLog.dependsOn assemble

liquibase {
    activities {
        main {
            changeLogFile props.getProperty("liquibase.changelog.main")
            referenceUrl props.getProperty("liquibase.changelog.referenceUrl")
            url props.getProperty("spring.datasource.url")
            username props.getProperty("spring.datasource.username")
            password props.getProperty("spring.datasource.password")
            referenceDriver "liquibase.ext.hibernate.database.connection.HibernateDriver"
        }
    }
}

这将在指定的changelog文件中生成一个变更日志。您可以首先使用 gradle generateChangelog 生成一个初始的变更日志,运行应用程序以将这些更改应用到数据库,然后在每次实体模型更改后运行 gradle diffChangelog 任务以获取这些更改并写入chanlog文件中。然后在再次运行diffChangeLog任务之前将其应用于数据库,以避免在changelog中出现重复操作。
为了使其工作,您需要在 liquibase.properties 中设置以下属性:
liquibase.changelog.main=src/main/resources/db/changelog/db.changelog-master.xml
liquibase.changelog.classpath=classpath:db/changelog/db.changelog-master.xml
liquibase.changelog.referenceUrl=hibernate:spring:<MODEL_PACKAGE>?dialect=org.hibernate.dialect.MySQL5Dialect

重要提示: 确保将<MODEL_PACKAGE>替换为您的Hibernate模型所在的包。


1

NB. 要应用Hazim的优秀答案,Spring Boot 2的referenceUrl参数应该有"&hibernate.physical_naming_strategy=org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy&hibernate.implicit_naming_strategy=org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy"


1
plugins {
    id 'org.liquibase.gradle' version '2.0.1'
}

在我将构建资源和类添加到Gradle liquibase插件的运行时依赖项后,该插件对我有效,如下所示:
dependencies {
    liquibaseRuntime 'org.liquibase:liquibase-core:3.5.3'
    liquibaseRuntime 'org.liquibase:liquibase-groovy-dsl:2.0.1'
    liquibaseRuntime 'mysql:mysql-connector-java:5.1.34'
    liquibaseRuntime 'org.liquibase.ext:liquibase-hibernate4:3.6'
    liquibaseRuntime 'javax.persistence:javax.persistence-api:2.2'
    liquibaseRuntime files('build/classes/java/main')
    liquibaseRuntime files('build/resources/main')

    // Your other dependencies...
}

我将其主要活动定义为:

liquibase {
  activities {
    main {
      changeLogFile 'build/liquibase_change_log.xml'
      url 'jdbc:mysql://localhost/YOURDATABASE'
      username 'YOURUSER'
      password 'YOURPASSWORD'
      driver 'com.mysql.jdbc.Driver'
      referenceUrl 'hibernate:classic:/hibernate.cfg.xml'      
    }
  }
}

请注意,我只是使用经典的Hibernate配置来定义源模式。
Liquibase的hibernate4集成会在运行liquibase的JVM类路径中查找/hibernate.cfg.xml。它还需要找到您的模式类。
我还添加了这个:
diffChangeLog.dependsOn build

0
liquibase {
activities {
    main {
        changeLogFile 'src/main/resources/liquibase-changeLog-db1.xml'
        classpath "$projectDir/src/main/resources"
        url props["database.db1.url"]
        referenceUrl props["database.db3.url"]
        username props["database.db1.user"]
        password props["database.db1.password"]
        referenceUsername props["database.db3.user"]
        referencePassword props["database.db3.password"]

    }
    secondary {
        changeLogFile 'src/main/resources/liquibase-changeLog-db2.xml'
        classpath "$projectDir/src/main/resources"
        url props["database.db2.url"]
        username props["database.db2.user"]
        password props["database.db2.password"]
    }
    tertiary {
        changeLogFile 'src/main/resources/liquibase-changeLog-db1.xml'
        classpath "$projectDir/src/main/resources"
        url props["database.db3.url"]
        username props["database.db3.user"]
        password props["database.db3.password"]
    }
    runList =  project.ext.runList
}

}

当你运行命令./gradlew diff prunList=main时,它将使用主数据库与参考数据库进行比较,并以以下格式在控制台中打印出差异。您可能需要在applications.properties文件中添加数据库URL和密码。在我的application.properties文件中,我定义了3个数据库。在我的第一个和第三个数据库中,它们几乎相同,除了一个小列添加。在下面的差异中,它已经识别出了缺失的列。

Compared Schemas: liquibase_new -> liquibase2
Product Name: EQUAL
Product Version: EQUAL
Missing Catalog(s): NONE
Unexpected Catalog(s): NONE
Changed Catalog(s): NONE
Missing Column(s):
     liquibase_new.business_center.new
Unexpected Column(s):
     liquibase2.business_center.new_column
Changed Column(s): NONE
Missing Foreign Key(s): NONE
Unexpected Foreign Key(s): NONE
Changed Foreign Key(s): NONE
Missing Index(s): NONE
Unexpected Index(s): NONE
Changed Index(s): NONE
Missing Primary Key(s): NONE
Unexpected Primary Key(s): NONE
Changed Primary Key(s): NONE
Missing Sequence(s): NONE
Unexpected Sequence(s): NONE
Changed Sequence(s): NONE
Missing Table(s): NONE
Unexpected Table(s): NONE
Changed Table(s): NONE
Missing Unique Constraint(s): NONE
Unexpected Unique Constraint(s): NONE
Changed Unique Constraint(s): NONE
Missing View(s): NONE
Unexpected View(s): NONE
Changed View(s): NONE

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接