将 liquibase 添加到现有 Spring Boot 项目的正确方法

Ksh*_*rya 5 database-migration liquibase spring-boot

我有一个现有的 Spring Boot 项目和一个相同的数据库。现在,我想添加 liquibase 来处理进一步的数据库迁移。执行此操作的正确步骤是什么?

我已经按照这篇文章添加了 liquibase 并生成了变更日志。我发现的大多数文章都在谈论从头开始在项目中使用 liquibase 或者对实现不太详细。到目前为止,我已经完成了以下工作:

在 pom.xml 中添加了依赖项和插件

<dependencies>
    //..other dependencies
    <dependency>
        <groupId>org.liquibase</groupId>
        <artifactId>liquibase-core</artifactId>
    </dependency>
    <dependency>
        <groupId>org.liquibase</groupId>
        <artifactId>liquibase-maven-plugin</artifactId>
        <version>3.6.2</version>
    </dependency>
</dependencies>

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
        <plugin>
            <groupId>org.liquibase</groupId>
            <artifactId>liquibase-maven-plugin</artifactId>
            <version>3.6.2</version>
            <configuration>
                <propertyFile>src/main/resources/liquibase.properties</propertyFile>
            </configuration>
        </plugin>
    </plugins>
</build>
Run Code Online (Sandbox Code Playgroud)

在 src/main/resources 下添加 liquibase.properties 文件

url=jdbc:mysql://localhost:3306/demodb
username=root
password=root
driver=com.mysql.jdbc.Driver
outputChangeLogFile=src/main/resources/db/changelog/changes/demodb-changelog.xml
Run Code Online (Sandbox Code Playgroud)

更新了 src/main/resources 下的 application.properties 文件以处理变更日志

#Hibernate
spring.datasource.url=jdbc:mysql://localhost:3306/demodb
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.username=root
spring.datasource.password=root

#Jpa
spring.jpa.hibernate.ddl-auto=none
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect

#Liquibase
spring.liquibase.change-log=classpath:db/changelog/db.changelog-master.xml
Run Code Online (Sandbox Code Playgroud)

db.changelog-master.xml在 src/main/resources/db/changelog 下创建文件

<?xml version="1.0" encoding="UTF-8"?>

<databaseChangeLog
    xmlns="http://www.liquibase.org/xml/ns/dbchangelog/1.9" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation = "http://www.liquibase.org/xml/ns/dbchangelog/1.9
        http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-1.9.xsd">

</databaseChangeLog>
Run Code Online (Sandbox Code Playgroud)

运行 spring boot 应用程序,以便在数据库中创建两个新表 - DATABASECHANGELOG(此时为空)和DATABASECHANGELOGLOCK(此时有一个空条目)

demodb-changelog.xml从终端生成文件以创建数据库当前状态的更改日志

mvn liquibase:generateChangeLog
Run Code Online (Sandbox Code Playgroud)

然后在执行时同步当前更改日志,liquibase.properties添加:

changeLogFile=src/main/resources/db/changelog/changes/demodb-changelog.xml
Run Code Online (Sandbox Code Playgroud)

然后从终端运行:

mvn liquibase:changelogSync
Run Code Online (Sandbox Code Playgroud)

现在,该DATABASECHANGELOG表具有执行时更改日志的条目。

接下来在db.changelog-master.xml文件中,添加生成的文件:

<include file="db/changelog/changes/demodb-changelog.xml"/>
Run Code Online (Sandbox Code Playgroud)

现在,当我运行该应用程序时,出现异常:

Caused by: liquibase.exception.MigrationFailedException: 
Migration failed for change set db/changelog/changes/demodb-changelog.xml
Reason: liquibase.exception.DatabaseException: Table 'abc' already exists
Run Code Online (Sandbox Code Playgroud)

因此,这是尝试再次运行更改日志文件。如何配置为仅运行那些尚未运行的变更集?我以为 的功能DATABASECHANGELOG是处理已执行的变更集,但我想我在这里错了。

我可以在没有include标记的情况下运行应用程序db.changelog-master.xml,但我想所有的变更日志文件都需要在这里列出,因为如果我要在不同的机器上运行这个应用程序以从头开始创建整个数据库,我将需要所有的变更日志文件。

那么如何配置 liquibase 只运行尚未执行的变更日志呢?

Mah*_*n M 2

MySQL将在表中维护liquibase的日志,

Liquibase 使用 DATABASECHANGELOG 表来跟踪已运行的变更集。

每当更改日志运行时,对于每个更改日志都会在表中添加一行,根据 ids 我们可以知道运行了哪些更改日志,

有一些标志,如runAlwaysrunOnChange,这些将帮助我们执行/不执行。

你可以参考:

For understanding flags:
Run Code Online (Sandbox Code Playgroud)

https://www.liquibase.org/documentation/changeset.html

For understanding DATABASECHANGELOG Table: 
Run Code Online (Sandbox Code Playgroud)

https://www.liquibase.org/documentation/databasechangelog_table.html