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

时间:2019-04-09 15:55:45

标签: java maven spring-boot liquibase

我正在学习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]

3 个答案:

答案 0 :(得分:1)

这在许多项目中都是很常见的情况。

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

此问题没有标准化

为避免向多个属性提供相同的值(这很容易出错),建议您使用引用。

# 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}可以直接使用。

答案 1 :(得分:1)

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>

一种更简单的选择是在没有maven插件的应用程序外部配置liquibase。

下载库,或使用某些程序包管理器进行安装,然后使用所有设置启动命令行

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

对其他设置执行相同操作

答案 2 :(得分: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集成和Maven插件推断出的更改日志路径相同。