如何在 Spring Boot 中配置 Maven Liquibase 插件?

     2023-02-26     54

关键词:

【中文标题】如何在 Spring Boot 中配置 Maven Liquibase 插件?【英文标题】:How can I configure Maven Liquibase plugin in Spring Boot? 【发布时间】:2019-08-30 23:35:24 【问题描述】:

我正在学习 Liquibase 和 Spring Boot,所以我用Spring Initializr 创建了一个简单的项目。

在我添加的 POM.xml 文件中:

    <plugin>
        <groupId>org.liquibase</groupId>
        <artifactId>liquibase-maven-plugin</artifactId>
        <version>3.4.1</version>
        <configuration>
            <propertyFile>src/main/resources/application.properties</propertyFile>
        </configuration>
    </plugin>

我已将 application.properties 指定为属性文件,因此我的应用程序的所有配置都可以在单个文件中进行。

当我从 IntelliJ 运行任何 liquibase-maven-plugin 任务时,我会收到不同的错误,这是一个运行 changeLogSync 任务的示例:

[ERROR] Failed to execute goal org.liquibase:liquibase-maven-plugin:3.4.1:changelogSync (default-cli) on project simpleTest: The changeLogFile must be specified

如果我在 application.properties 中添加正确的键,我就能让它工作。

例如,我发现 liquibase-maven-plugin 不会读取 spring.datasource.url 属性,但它只会读取 url 属性。

因此,我的 application.properties 必须是类似的:

environment                         = JUnit
spring.datasource.url               = jdbc:h2:file:./target/test
spring.datasource.driver-class-name = org.h2.Driver
spring.datasource.username          = sa
spring.datasource.password          = sa
spring.liquibase.change-log         = classpath:/db/changelog/db.changelog-master.yaml
spring.h2.console.enabled           = true
spring.h2.console.path              = /h2-console


# Keys needed for liquibase maven plugin
url                                 = jdbc:h2:file:./target/test
username                            = sa
password                            = sa

如果我遵循这种模式,我最终会在 application.properties 中拥有几个名称稍有不同但值相同的键,这种解决方案显然非常丑陋且效率低下。

在 Spring Boot 中配置和使用 Liquibase Maven 插件的高效且可维护的方法是什么?

在收到 Amith Kumar 的答复后进行编辑:

environment=JUnit
spring.datasource.url=jdbc:h2:file:./target/glossary-test
spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=sa
spring.liquibase.change-log=classpath:/db/changelog/db.changelog-master.yaml
spring.h2.console.enabled=true
spring.h2.console.path=/h2-console
url=$spring.datasource.url
changeLogFile=$spring.liquibase.change-log
username=$spring.datasource.username
password=$spring.datasource.password

编辑后出错:

[ERROR] Failed to execute goal org.liquibase:liquibase-maven-plugin:3.4.1:dropAll (default-cli) on project test: Error setting up or running Liquibase: liquibase.exception.DatabaseException: java.lang.RuntimeException: Cannot find database driver: Driver class was not specified and could not be determined from the url ($spring.datasource.url) -> [Help 1]

【问题讨论】:

【参考方案1】:

Liquibase maven 插件支持通过 pom.xml 进行配置注入。

因此,您可以使用properties-maven-plugin 将您的属性包含在 application.properties 中(如果您使用的是 application.yml,则使用 yaml-properties-maven-plugin),然后将它们注入到 liquibase 配置中:

示例:

<plugin>
    <groupId>it.ozimov</groupId>
    <artifactId>yaml-properties-maven-plugin</artifactId>
    <version>1.1.3</version>
    <executions>
                    <execution>
                            <phase>initialize</phase>
                            <goals>
                                    <goal>read-project-properties</goal>
                            </goals>
                            <configuration>
                                    <files>
                                            <file>src/main/resources/application.yml</file>
                                    </files>
                            </configuration>
                    </execution>
     </executions>
</plugin>

现在您可以在 liquibase 配置中注入这些属性:

<plugin>
            <groupId>org.liquibase</groupId>
            <artifactId>liquibase-maven-plugin</artifactId>
            <version>3.8.1</version>
            <configuration>
                <changeLogFile>src/main/resources/db/changelog/db.changelog-master.yaml</changeLogFile>
                <driver>$spring.datasource.driverClassName</driver>
                <url>$spring.datasource.url</url>
                <username>$spring.datasource.username</username>
                <password>$spring.datasource.password</password>
                <promptOnNonLocalDatabase>false</promptOnNonLocalDatabase>
                <databaseChangeLogTableName>DATABASECHANGELOG</databaseChangeLogTableName>
                <databaseChangeLogLockTableName>DATABASECHANGELOGLOCK</databaseChangeLogLockTableName>
            </configuration>
            <dependencies>
                <dependency>
                    <groupId>javax.xml.bind</groupId>
                    <artifactId>jaxb-api</artifactId>
                    <version>2.3.0</version>
                </dependency>
            </dependencies>
</plugin>

我还需要设置logicalFilePath,以确保spring boot集成推断的changelog路径和maven插件所在的地方一致。

【讨论】:

【参考方案2】:

application.properties 设置可以快速启动并运行应用程序,但在灵活性方面不是最佳解决方案

我的建议是使用@Configuration 配置数据源,例如here

然后配置上面定义的liquibase传递数据源如下

@Configuration
public class LiquibaseConfigurer 

    @Autowired
    @Qualifier("primaryDataSource")
    private DataSource oltpDataSource;

    @Bean
    @DependsOn
    public SpringLiquibase liquibase() 
        SpringLiquibase liquibase = new SpringLiquibase();
        liquibase.setChangeLog("classpath:liquibase/liquibase-changelog.xml");
        liquibase.setDataSource(oltpDataSource);
        return liquibase;
    

在这种情况下你只需要liquibase-core 依赖如下

    <dependency>
        <groupId>org.liquibase</groupId>
        <artifactId>liquibase-core</artifactId>
    </dependency>

一个更简单的替代方法是在应用程序外部配置 liquibase,而不使用 maven 插件。

下载库,或者使用一些包管理器安装它,然后启动一个包含所有设置的命令行

liquibase --driver=org.h2.Driver \
     --classpath=/path/to/h2/driver.jar \
     --changeLogFile=/db/changelog/db.changelog-master.yaml \
     --url="jdbc:h2:file:./target/glossary-test" \
     --username=sa \
     --password=sa \
     --logLevel=debug \
     migrate

不管怎样,你现在遇到的问题是因为你写了这个:

url=$spring.datasource.url

我不知道您在哪里找到此语法,但尝试复制连接 url 并替换为以下内容

url=jdbc:h2:file:./target/test

对其他设置执行相同操作

【讨论】:

我从 Amith 收到的另一个答案中建议了 $ 符号。虽然我认为这是一个普遍的想法,但在使用 Maven Liquibase 插件时它不起作用。当您在控制台中启动其中一项任务时,它会打印“属性文件中的'spring.datasource.url'未被此任务使用。”。感谢灵活的解决方案和回购链接:) 是的,正是我想说的(占位符在那里不起作用) 您知道,spring boot 开箱即用地为您管理 liquibase。除非您的项目中有多个数据源或者您偏离了 Spring 默认配置,否则您不需要明确需要 DataSourceSpringLiquibase bean。请参考 spring documentation & sample spring git project from pivotal。 我对 hikaricp、url 和数据源也有一些问题。不幸的是,我现在不记得细节了。我一般来说这种设置的“问题”是它们适合非常基本的场景或原型应用程序。 如果我想使用回滚目标,我该怎么做?我认为类方法对于 maven 目标无关紧要,对吧?有差距……【参考方案3】:

这在许多项目中很常见。

当您使用多个插件/库时,每个插件/库都需要环境配置中的某些属性,其中键名在其本机命名法中定义。

没有针对此问题的标准化

为了避免为多个属性提供相同的值,容易出错,建议使用引用。

# Keys needed for liquibase maven plugin
url=$spring.datasource.url

更新

我注意到您在运行 liquibase maven 插件时遇到了异常,该插件当然是在 spring 上下文之外运行的。我之前提供的解决方案适用于 spring 上下文,即当您启动应用程序时。 对于给定的场景,使用 maven filter resource files 功能。所以你的命令会变成

mvn liquibase:generateChangeLog 资源:资源

您的设置将如下所示:

src/main/filters/filter.properties

db.url=jdbc:h2:file:./target/glossary-test
db.username=sa
db.password=sa
db.driver=org.h2.Driver
db.lb.changeLogFile=classpath:/db/changelog/db.changelog-master.yaml

application.properties

spring.datasource.url=@db.url@
spring.datasource.username=@db.username@
spring.datasource.password=@db.password@
spring.datasource.driver-class-name=@db.driver@
url=@db.url@
username=@db.username@
password=@db.password@
driver=@db.driver@
changeLogFile=@db.lb.changeLogFile@

pom.xml

<build>
......
    <plugins
        ......
        <plugin>
            <groupId>org.liquibase</groupId>
            <artifactId>liquibase-maven-plugin</artifactId>
            <version>3.6.3</version>
            <configuration>
                <propertyFile>target/classes/application.properties</propertyFile>
            </configuration>
        </plugin>

    </plugins>

    <filters>
        <filter>src/main/filters/filter.properties</filter>
    </filters>
    <resources>
        <resource>
            <directory>src/main/resources</directory>
            <filtering>true</filtering>
        </resource>
    </resources>
</build>

请参阅我的 github project 以获得完整的工作解决方案。查看您定义了公共属性的filter.properties 文件,然后在application.properties 文件中引用相同的内容。

注意:由于这是一个 spring 项目,因此不能将 $propertyName 用于 maven 过滤器文件作为 spring 的保留属性占位符语法,而是使用 @propertyName@。对于非弹簧项目$propertyName 将开箱即用。

【讨论】:

您好!我试过你的建议,我得到:liquibase.exception.DatabaseException:java.lang.RuntimeException:找不到数据库驱动程序:未指定驱动程序类,无法从 url ($spring.datasource.url) 您好,我希望您在文件中定义属性时,中间没有空格。为了便于阅读,这里只显示了它。您的实际文件应如下所示:spring.datasource.url=jdbc:h2:file:./target/test # Keys needed for liquibase maven plugin url=$spring.datasource.url 注意: 用于描述新行,因为它不允许在 SO cmets 中使用 嗨@Amith Kumar,我已经尝试过你的建议,但我得到了同样的错误。我已经用新的配置和错误数据更新了问题。 用示例项目参考和更多细节更新了我的解决方案,这应该适合你。 属性文件需要相同,对于应用程序要么是 liquibase.如果您使用不同的文件将无法正常工作。或者,如果您使用不同的格式,例如应用程序的“.yml”和 liquibase 的“属性”,也将不起作用。

如何通过 Maven 使用 Netbeans 调试 Spring Boot

】如何通过Maven使用Netbeans调试SpringBoot【英文标题】:HowtodebugSpringBootwithNetbeansviaMaven【发布时间】:2017-05-2817:47:21【问题描述】:在我用SpringBoot1.4.3在Netbeans8.2中进行了正确的调试设置之后,我想我把我的发现写下来作为其他人... 查看详情

使用 Spring Boot 和多模块的 Maven 配置 - 在 Intellij 中运行应用程序

】使用SpringBoot和多模块的Maven配置-在Intellij中运行应用程序【英文标题】:MavenconfigurationwithSpringBoot&multimodules-runapplicationinIntellij【发布时间】:2015-05-2905:26:34【问题描述】:我目前正在使用SpringBoot开发RESTAPI。我是Maven新手,... 查看详情

如何在我的 Maven Spring Boot 多模块项目的测试中引用兄弟模块?

】如何在我的MavenSpringBoot多模块项目的测试中引用兄弟模块?【英文标题】:Howtoreferencesiblingmoduleinatestformymavenspringbootmulti-moduleproject?【发布时间】:2020-03-2023:02:05【问题描述】:如何在Maven中包含兄弟模块作为我的SpringBoot测试... 查看详情

使用“spring-boot-starter-parent”时如何在 Maven 中使用较低的 Elastic 搜索版本

】使用“spring-boot-starter-parent”时如何在Maven中使用较低的Elastic搜索版本【英文标题】:HowtouselowerElasticsearchversioninMavenwhenusing"spring-boot-starter-parent"【发布时间】:2017-11-0920:39:18【问题描述】:我正在为Webflux使用版本为“... 查看详情

在 Spring Boot 测试中排除配置

】在SpringBoot测试中排除配置【英文标题】:ExcludingConfigurationinSpringboottest【发布时间】:2018-11-0218:37:49【问题描述】:我在一个Maven项目中有以下设置。生产代码的配置类:packagecom.example;@ConfigurationpublicclassMyConfiguration@BeanpublicAbe... 查看详情

使用 maven 插件设置时 Spring Boot 配置文件不活动

】使用maven插件设置时SpringBoot配置文件不活动【英文标题】:SpringBootprofilesnotactivewhensetwithmavenplugin【发布时间】:2016-08-0911:29:06【问题描述】:我正在尝试在启动Tomcat以在maven中进行集成测试时设置spring配置文件,如下所示:...... 查看详情

在 Spring Boot 的 application.properties 中使用 Maven 属性

】在SpringBoot的application.properties中使用Maven属性【英文标题】:UsingMavenpropertiesinapplication.propertiesinSpringBoot【发布时间】:2016-08-1018:04:13【问题描述】:我正在尝试将pom.xml中的属性加载到application.properties。我想创建两个配置文件... 查看详情

Spring Boot:使用 yaml 中配置的 Maven 属性

】SpringBoot:使用yaml中配置的Maven属性【英文标题】:SpringBoot:useofMavenpropertiesconfiguredinyaml【发布时间】:2017-11-0712:31:05【问题描述】:我正在尝试从Maven中提取一些属性并在我的应用程序启动时打印它们。我正在使用SpringBoot,因... 查看详情

如何在 OpenShift 上部署多模块 maven spring boot 应用程序

】如何在OpenShift上部署多模块mavenspringboot应用程序【英文标题】:Howtodeploymulti-modulemavenspringbootapplicationonOpenShift【发布时间】:2016-12-3010:47:03【问题描述】:我有一个多模块spring-boot项目,我想在Openshift上部署它,我也在那里安... 查看详情

如何将 Spring Boot 项目集成到已经存在的多模块 Maven 项目中?

】如何将SpringBoot项目集成到已经存在的多模块Maven项目中?【英文标题】:HowtointegrateaSpringBootprojectintoanalreadyexistingmulti-moduleMavenproject?【发布时间】:2016-12-1709:26:35【问题描述】:我有一个多模块Maven项目,它有一个带有一系列... 查看详情

如何在 maven pom.xml 文件中拥有另一个父依赖项以及 Spring Boot 父项?

】如何在mavenpom.xml文件中拥有另一个父依赖项以及SpringBoot父项?【英文标题】:HowtohaveanotherparentdependencyaswellasSpringBootparentinmavenpom.xmlfile?【发布时间】:2018-07-2408:32:51【问题描述】:我目前正在开发一个SpringBoot多模块项目。当... 查看详情

如何在 Spring Boot 中测试配置类

】如何在SpringBoot中测试配置类【英文标题】:HowtotestaconfigurationclassinSpringBoot【发布时间】:2021-05-2207:45:19【问题描述】:我有以下SpringBoot配置类,以便在我们的MongoDB中创建索引:@Configuration@DependsOn("mongoTemplate")@Profile("!test")publ... 查看详情

如何在 Spring Boot 中配置 Tomcat 关闭端口?

】如何在SpringBoot中配置Tomcat关闭端口?【英文标题】:HowtoconfigureTomcatshutdownportinSpringBoot?【发布时间】:2017-09-1223:12:50【问题描述】:寻找如何在SpringBoot应用程序中配置关闭端口的方法。【问题讨论】:【参考方案1】:我不认... 查看详情

如何在 spring-boot 中配置 Jetty(很容易?)

】如何在spring-boot中配置Jetty(很容易?)【英文标题】:HowtoconfigureJettyinspring-boot(easily?)【发布时间】:2013-12-2514:34:17【问题描述】:按照本教程,我可以使用以下依赖项启动运行Jetty的spring-boot。<dependency><groupId>org.spri... 查看详情

如何在 Spring Boot 中配置多个慰藉队列

】如何在SpringBoot中配置多个慰藉队列【英文标题】:Howtoconfiguremultiplesolacequeuesinspringboot【发布时间】:2019-09-1108:33:17【问题描述】:我正在尝试使用以下代码在我的SpringBoot应用程序中配置多个SOLACE队列:@ConfigurationpublicclassJmsCo... 查看详情

如何在 spring-boot 中禁用 spring-data-mongodb 自动配置

】如何在spring-boot中禁用spring-data-mongodb自动配置【英文标题】:Howtodisablespring-data-mongodbautoconfigurationinspring-boot【发布时间】:2015-04-2903:39:04【问题描述】:有没有人试过在spring-boot中禁用mongodb的自动配置?我正在尝试使用spring-d... 查看详情

如何在 Spring Boot 中使用 Spring Security 配置 CORS? [复制]

】如何在SpringBoot中使用SpringSecurity配置CORS?[复制]【英文标题】:HowtoconfigureCORSinspringbootwithspringsecurity?[duplicate]【发布时间】:2021-11-0605:12:41【问题描述】:我的CORS有问题。我有以下安全配置:@Configuration@EnableWebSecuritypublicclassS... 查看详情

如何使用 Gradle + Spring boot 运行多个配置文件? [复制]

】如何使用Gradle+Springboot运行多个配置文件?[复制]【英文标题】:HowcanIrunmultipleprofileswithGradle+Springboot?[duplicate]【发布时间】:2020-01-2115:04:56【问题描述】:我正在尝试从maven学习使用带有springboot的gradle,所以我想知道如何在命... 查看详情