Using Liquibase MongoDB

Liquibase 是一个用于数据库架构更改管理的开源工具,它允许通过 MongoDB Extension 管理 MongoDB 数据库。 Quarkus 提供一级支持以使用 Liquibase MongoDB 扩展,本指南对此进行了解释。

Solution

我们建议您遵循接下来的部分中的说明,按部就班地创建应用程序。然而,您可以直接跳到完成的示例。

克隆 Git 存储库: git clone $${quickstarts-base-url}.git,或下载 $${quickstarts-base-url}/archive/main.zip[存档]。

解决方案位于 liquibase-mongodb-quickstart directory

Setting up support for Liquibase

若要开始将 Liquibase MongoDB 扩展与您的项目一起使用,您只需:

  • 将您的 changeLog 添加到 src/main/resources/db/changeLog.xml 文件中,正如您通常使用 Liquibase 所做的一样

  • 激活 migrate-at-start 选项以自动迁移模式或注入 Liquibase 对象并按您通常的方式运行迁移。

您可以通过在项目基本目录中运行以下命令将 liquibase-mongodb 扩展添加到您的项目中:

CLI
quarkus extension add {add-extension-extensions}
Maven
./mvnw quarkus:add-extension -Dextensions='{add-extension-extensions}'
Gradle
./gradlew addExtension --extensions='{add-extension-extensions}'

这会将以下内容添加到构建文件中:

pom.xml
<dependency>
    <groupId>io.quarkus</groupId>
    <artifactId>quarkus-liquibase-mongodb</artifactId>
</dependency>
build.gradle
implementation("io.quarkus:quarkus-liquibase-mongodb")

Liquibase MongoDB 扩展支持依赖于 Quarkus MongoDB 客户端配置。目前,它不支持多个客户端。您需要将 MongoDB 配置添加到 application.properties 文件中,以便允许 Liquibase 管理架构。

以下是 application.properties 文件的一个示例:

# configure MongoDB
quarkus.mongodb.connection-string = mongodb://localhost:27017

# Liquibase MongoDB minimal config properties
quarkus.liquibase-mongodb.migrate-at-start=true

# Liquibase MongoDB optional config properties
# quarkus.liquibase-mongodb.change-log=db/changeLog.xml
# quarkus.liquibase-mongodb.validate-on-migrate=true
# quarkus.liquibase-mongodb.clean-at-start=false
# quarkus.liquibase-mongodb.contexts=Context1,Context2
# quarkus.liquibase-mongodb.labels=Label1,Label2
# quarkus.liquibase-mongodb.default-catalog-name=DefaultCatalog
# quarkus.liquibase-mongodb.default-schema-name=DefaultSchema

Liquibase MongoDB 使用连接字符串进行配置,我们会尽力构建与 MongoDB 客户端配置匹配的连接字符串,但如果某些配置属性不起作用,您可以考虑将它们直接添加到 quarkus.mongodb.connection-string 配置属性中。

根据 Liquibase 命名约定,将 changeLog 文件添加到默认文件夹中:changeLog 支持 `src/main/resources/db/changeLog.xml`YAML、JSON 和 XML 格式。

<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog
        xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
        xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-latest.xsd
        http://www.liquibase.org/xml/ns/dbchangelog-ext https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd">

    <changeSet id="1" author="loic">
        <ext:createCollection collectionName="Fruit"/>

        <ext:createIndex collectionName="Fruit">
            <ext:keys>{color: 1}</ext:keys>
            <ext:options>{name: "colorIdx"}</ext:options>
        </ext:createIndex>

        <ext:insertOne collectionName="Fruit">
            <ext:document>{"name":"orange", "color": "orange"}</ext:document>
        </ext:insertOne>
    </changeSet>

</databaseChangeLog>

现在可以启动应用程序,然后 Quarkus 会根据配置运行 Liquibase 的更新方法。

Using the Liquibase object

如果你有兴趣直接使用 Liquibase 对象,你可以按如下方式注入它:

如果你启用了 quarkus.liquibase.migrate-at-start 属性,那么当你在使用 Liquibase 实例时,Quarkus 已经运行了迁移操作。

import io.quarkus.liquibase.LiquibaseFactory;

@ApplicationScoped
public class MigrationService {
    // You can Inject the object if you want to use it manually
    @Inject
    LiquibaseMongodbFactory liquibaseMongodbFactory; 1

    public void checkMigration() {
        // Use the liquibase instance manually
        try (Liquibase liquibase = liquibaseFactory.createLiquibase()) {
            liquibase.dropAll(); 2
            liquibase.validate();
            liquibase.update(liquibaseFactory.createContexts(), liquibaseFactory.createLabels());
            // Get the list of liquibase change set statuses
            List<ChangeSetStatus> status = liquibase.getChangeSetStatuses(liquibaseFactory.createContexts(), liquibaseFactory.createLabels()); 3
        }
    }
}
1 Inject the LiquibaseFactory object
2 直接使用 Liquibase 实例
3 已应用或未应用的 Liquibase ChangeSets 列表

Liquibase Mongodb on Kubernetes

有时,最好不要在每次应用程序启动时执行 Liquibase 初始化。一个这样的例子是在 Kubernetes 上部署,在 Kubernetes 上每个副本执行 Liquibase 没有意义。相反,最好执行它一次,然后在没有 Liquibase 的情况下启动实际应用程序。为了支持这种用例,当为 Kubernetes 生成清单时,生成的清单包含 Liquibase 的 Kubernetes 初始化 JobJob 执行初始化,实际 Pod 将在 Job 成功完成后启动。

Disabling

此功能默认启用,可以使用以下内容进行全局禁用:

quarkus.kubernetes.init-task-defaults.enabled=false

或在 OpenShift 上:

quarkus.openshift.init-task-defaults.enabled=false

Using a custom image that controls waiting for the Job

若要更改默认`groundnuty/k8s-wait-for:no-root-v1.7` 的 wait-for 图像,可以使用:

quarkus.kubernetes.init-task-defaults.wait-for-container.image=my/wait-for-image:1.0

或在 OpenShift 上:

quarkus.openshift.init-task-defaults.wait-for-container.image=my/wait-for-image:1.0

Note: 在此上下文中,全局意味着 for all extensions that support init task externalization.

Configuration Reference

Unresolved include directive in modules/ROOT/pages/liquibase-mongodb.adoc - include::../../../target/quarkus-generated-doc/config/quarkus-liquibase-mongodb.adoc[]