【问题标题】:Spring Boot: run liquibase migrations without starting appSpring Boot:在不启动应用程序的情况下运行 liquibase 迁移
【发布时间】:2018-09-07 00:43:35
【问题描述】:

在 Spring Boot 中,the documentation 似乎鼓励在应用启动时运行迁移。

这很好,但有时应用程序启动可能会产生我不想打扰的副作用/依赖项 - 我只想自己运行迁移。想想只是设置一个本地开发数据库,​​在其中四处寻找,甚至无需运行应用程序。

相比之下,在 Dropwizard 中,单独运行迁移 is straightforward 并带有应用的内置参数,就像这样

java -jar hello-world.jar db migrate helloworld.yml

Spring Boot 有什么等价物吗?还是我只需要直接下拉并运行 liquibase?

我有兴趣直接回答,但也有兴趣看看我是否误解了更高层次的东西 - 比如也许这种在启动时运行的方法通常“更好”,因为某些原因我没有尚未发现,因此 Spring Boot 鼓励您完全采用这种方式作为设计选择。

【问题讨论】:

  • 您是否尝试过运行特定的 liquibase maven 目标 liquibase:updateliquibase.org/documentation/maven/maven_update.html
  • 可以通过配置禁用吗? :stackoverflow.com/questions/41491234/…
  • 我们希望在部署容器之前在 CI/CD 管道中执行此操作。否则,如果 Liquibase 在应用程序启动时运行,它将与每个毫无意义的自动缩放事件一起运行。我认为您还没有找到解决方案?
  • @DarthPablo 不,从未找到解决方案。除非切换回 Dropwizard 很重要 ;-) 事实上,好点,就像您可能不希望在只想运行迁移时运行应用程序产生副作用一样,反之亦然。有趣的设计选择,从来没有找到任何令人信服的论据证明它是一种更好的方法或有其他我不知道的好处 - 我想这真的很明显,它很方便你永远不会在没有运行最新迁移的情况下意外启动应用程序,但我不确定轻微的专业可以弥补这里的缺点。
  • “否则,如果 Liquibase 在应用程序启动时运行,它将与每个毫无意义的自动缩放事件一起运行”@DarthPablo 当没有要应用的迁移时,Liquibase 只需半秒即可比较与您的迁移文件一起在数据库中应用的迁移列表 - 这对我们来说从来都不是问题。如果您同时启动应用程序的 2 个实例,它们不会相互干扰,因为 Liquibase 使用数据库锁来确保一次只有一个实例在处理迁移。

标签: java spring-boot liquibase


【解决方案1】:

我知道这是一个老问题,但如果其他人偶然发现它,这可能会有用。

您可以为您的应用定义一个命令行参数,您将使用该参数仅启动将运行迁移的应用上下文的一部分。

这是 Kotlin 中的一个示例:

import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
import org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration
import org.springframework.boot.builder.SpringApplicationBuilder
import org.springframework.boot.runApplication
import org.springframework.context.annotation.AnnotationConfigApplicationContext
import org.springframework.context.annotation.Import

@SpringBootApplication
class Application

@Import(DataSourceAutoConfiguration::class, LiquibaseAutoConfiguration::class)
class LiquibaseInit

fun main(args: Array<String>) {
    if (args.contains("dbinit")) {
        SpringApplicationBuilder(LiquibaseInit::class.java)
            .contextClass(AnnotationConfigApplicationContext::class.java)
            .run(*args)
        return
    }

    runApplication<Application>(*args)
}

我们在这里声明了 2 个类:Application(具有@SpringBootApplication 注释的主应用程序类)和LiquiBaseInit(具有@DataSourceAutoConfiguration@LiquibaseAutoConfiguration),第一个将启动整个上下文,而后者只会启动 Liquibase 运行迁移所需的 bean。

在 main 函数中,我们检查参数数组是否有字符串 dbinit,如果存在,我们从 LiquiBaseInit 类启动应用程序上下文。

现在您可以像这样使用您的 jar 文件运行迁移:

java -jar hello-world.jar dbinit

如果您要在 Kubernetes 中运行您的应用程序,您可能还想查看我博客中的这篇文章:https://blog.monosoul.dev/2021/12/26/using-liquibase-with-kubernetes/

【讨论】:

    【解决方案2】:

    This answer 提到了一个在 Liquibase 之后运行的钩子。在那个问题中,它被用来填充数据库,可能带有测试或默认值。

    @Bean
    @DependsOn("liquibase")
    public YourBean yourBean() {
        return new YourBean();
    }
    
    static class YourBean {
    
        @PostConstruct
        public void shutdown() {
             // Exit your application here.
             );
        }
    
    }
    

    这可能行得通。我不知道,你可能甚至可以访问 liquibase 模式,并且只有在“创建”时才会关闭。

    【讨论】:

      【解决方案3】:

      您可以使用不同的 Spring 配置文件:例如,使用名为“init”的配置文件,它将激活“liquibase”配置文件。

      application.yml:(默认禁用 Liquibase)

      spring:
        liquibase:
          enabled: false
      

      application-init.yml:(不运行web容器,所以spring启动后会自动关闭)

      spring:
        profiles:
          include: liquibase
        main:
          web-application-type: none
      

      spring-liquibase.yml:(启用 liquibase)

      spring:
        liquibase:
          enabled: true
          change-log: classpath:/db/changelog/changelog.xml
      

      此设置允许您将 Liquibase 作为初始化容器运行 (spring.profiles.active=init),但如果您愿意,您仍然可以将 Liquibase 作为 Web 应用程序的一部分运行 (spring.profiles.active=liquibase) .

      【讨论】:

        【解决方案4】:

        一般来说,在应用程序启动时运行迁移可能会减少工作量,特别是如果您使用的是 Spring Boot 并且它已经为您设置好了。然后,您可以停止应用程序。

        但是,如果您真的想在没有 Spring Boot 应用程序的情况下运行迁移,您可以使用 Liquibase Gradle 和 Maven 插件: https://github.com/liquibase/liquibase-gradle-plugin https://docs.liquibase.com/tools-integrations/maven/home.html

        这将要求您在另一个配置文件中设置数据库凭据,除了您的应用程序配置,以便插件可以连接到数据库。

        【讨论】:

          【解决方案5】:

          为此,我们创建了自己的脚本,它不仅可以生成迁移,还可以手动应用它们,但它只能从 gradle 应用,请参阅: https://github.com/Wissance/SpringUu

          要应用更新,我们使用以下命令:

          .\gradlew.bat update -PrunList='changesApply'
          

          指定数据库连接编辑gradle部分更改应用

          有关我们工具的更多详细信息,请参阅文章:

          https://m-ushakov.medium.com/code-first-with-spring-boot-hibernate-and-liquibase-48f5c9998d95

          【讨论】:

            【解决方案6】:

            U 可以设置和配置 maven liquibase 插件: https://docs.liquibase.com/tools-integrations/maven/commands/home.html

            它允许在不启动 spring boot 应用程序本身的情况下使用迁移

            可以设置为构建工件的一部分或类似单独的任务

            【讨论】:

              猜你喜欢
              • 2020-02-23
              • 1970-01-01
              • 2020-08-20
              • 2017-06-17
              • 2017-04-29
              • 1970-01-01
              • 2021-02-12
              • 2021-12-21
              • 2015-05-31
              相关资源
              最近更新 更多