Невозможно сгенерировать разницу с плагином для жидкостной базы

Я пытаюсь реализовать liquibase в существующем проекте SpringBoot с базой данных MYSQL. Я хочу иметь возможность генерировать наборы изменений, которые определяют различия при изменении объекта.

Что я сделал:

Я добавил зависимости от ликвидазы и плагин Gradle ликвидабазы ​​в моем build.gradle файл. После внесения изменений в домен я запустил gradle generateChangeLog, Команда выполняется успешно, но ничего не происходит.

Я где-то читал, что этот плагин Gradle работает только для базы данных H2 памяти? Это правда? Если да, то какую альтернативу я должен использовать для автоматического создания журналов изменений.

Я не смог найти работающий пример SpringBoot, основанный на gradle, который использует MYSQL и имеет встроенную жидкостную базу с возможностью автоматической генерации изменений. Было бы здорово, если бы кто-то мог это предоставить.

Рекомендации:

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

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

6 ответов

Решение

Решением является написать задание, которое вызывает 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, вы можете добавить значения напрямую, но это не очень хорошая практика.

Далее вам нужно будет применить liquibase.gradle файл изнутри проекта build.gradle файл. и добавить зависимость жидкой основы

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

После этого шага жидкость будет полностью настроена.

Теперь вы можете использовать gradle liquibaseDiffChangeLog генерировать журналы изменений.

При следующей настройке его можно использовать вместе с liquibase-hibernate а также liquibase-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"
        }
    }
}

Это создаст журнал изменений в указанном файле журнала изменений. Вы можете сначала создать начальный журнал изменений с помощьюgradle generateChangelogзапустите приложение, чтобы применить эти изменения к базе данных, а затем после каждого изменения в моделях сущностей запускайте gradle diffChangelogзадача получить эти изменения в файле чанлога. Затем их следует применить к базе данных перед запускомdiffChangeLog еще раз, чтобы предотвратить дублирование операций в журнале изменений.

Для этого вам понадобятся следующие свойства в 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> с пакетом, в котором находятся ваши модели гибернации.

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 ищет /hibernate.cfg.xml в пути к классам JVM, на которой выполняется Liquibase. Также потребуется найти классы вашей схемы.

Я также добавил это:

diffChangeLog.dependsOn build

NB. Чтобы применить отличный ответ от Хазима для 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"

У вас может быть пользовательская задача, как было упомянуто @Hazim и плагином gracle в liquibase, а также для создания чего-то кроме создания diff. Проверьте этот пост. Git Issue

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он возьмет основную базу данных и сравнит ее с эталонной базой данных и распечатает разницу в консоли в формате ниже. вам может потребоваться добавить URL-адреса и пароли db в файл applications.properties. здесь, в моем файле application.properties, я определил 3 dbs. в моем 1-м и 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
Другие вопросы по тегам