Java 如何从外部属性文件填充 Liquibase 参数值?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20610948/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 03:06:50  来源:igfitidea点击:

How can I populate Liquibase parameter values from an external properties file?

javamavenliquibase

提问by amoe

Is there any way that I can populate parametersin a Liquibase changelog file based on the contents of an external property file?

有什么方法可以根据外部属性文件的内容在 Liquibase 更改日志文件中填充参数

As in, I would like to be able to say:

就像在,我想能够说:

<createTable tableName="${table.name}">
     <column name="id" type="int"/>
     <column name="${column1.name}" type="varchar(${column1.length})"/>
     <column name="${column2.name}" type="int"/>
</createTable>

And keep the value of table.nameand the other parameters in an external file db.properties, and reference this file either from within the changelog, or from the Liquibase command line, or as an option of the Maven plugin that runs liquibase.

并将table.name和其他参数的值保留在外部文件中db.properties,并从更改日志中或从 Liquibase 命令行或作为运行 liquibase 的 Maven 插件的选项引用此文件。

I can't seem to find any way to do this, is it possible?

我似乎找不到任何方法来做到这一点,这可能吗?

采纳答案by Wooff

Do that at compile time: sounds like job for maven filtersand/or profiles

在编译时执行此操作:听起来像是 Maven过滤器和/或配置文件的工作

NOTE: be carefull with liquibase and any "marker" replacements... liquibase stores CRC of applied changessets

注意:小心 liquibase 和任何“标记”替换... liquibase 存储应用变更集的 CRC

pom.xml

pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>test</groupId>
    <artifactId>test</artifactId>
    <version>0.0.1-SNAPSHOT</version>

    <build>
        <filters>
            <filter>src/main/filters/liquibase.properties</filter>
        </filters>
        <resources>
            <resource>
                <directory>src/main/resources</directory>
                <filtering>true</filtering>
                <includes>
                    <include>liquibase.xml</include>
                </includes>
            </resource>
        </resources>
    </build>
</project>

/src/main/filters/liquibase.properties

/src/main/filters/liquibase.properties

table.name=TABLE_NAME
column1.name=COLUMN1_NAME
column1.length=10
column2.name=COLUMN2_NAME

/src/main/resources/liquibase.xml

/src/main/resources/liquibase.xml

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

    <changeSet author="me" id="changeSetId1">
        <comment>Test</comment>

        <createTable tableName="${table.name}">
            <column name="id" type="int" />
            <column name="${column1.name}" type="varchar(${column1.length})" />
            <column name="${column2.name}" type="int" />
        </createTable>
    </changeSet>

</databaseChangeLog>

EDIT: A typicalinvocation (using filteredresources) would look like this: mvn resources:resources liquibase:updateor more preferably use profiles... mvn resources:resources liquibase:update -P<profile_name>

编辑:典型的调用(使用过滤的资源)看起来像这样: mvn resources:resources liquibase:update或更优选地使用配置文件... mvn resources:resources liquibase:update -P<profile_name>

EDIT2: There is one big advantage of this way of defining columns. You could use this property's (e.g.: column1.length) value (e.g.: 10) for validation of everylayer: Hibernate, DAO, WEB, faces, JavaScript. Just use this property at each place where you need to validate against it. Even in i18n/messages.properties if needed (e.g.: input1.validation=No more than ${column1.length} letters.).

EDIT2:这种定义列的方式有一个很大的优势。您可以使用此属性的(例如:column1.length)值(例如:10)来验证一层:Hibernate、DAO、WEB、faces、JavaScript。只需在需要对其进行验证的每个地方使用此属性即可。如果需要,甚至在 i18n/messages.properties 中(例如:input1.validation=不超过 ${column1.length} 个字母。)。

The only complication is that if you need to change this value you need to provide proper liquibase update/rollback script. Sometimes it is possible to change value and set new liquibase checksum (safe operation like increase varchar length), but other times you need to create a safeupdate changescript using new property/value.

唯一的复杂之处在于,如果您需要更改此值,则需要提供适当的 liquibase 更新/回滚脚本。有时可以更改值并设置新的 liquibase 校验和(安全操作,如增加 varchar 长度),但有时您需要使用新属性/值创建安全更新更改脚本。

回答by Maksim

Take a look at here. You can either use a command line arguments (-D[arg name]=[arg value]) or environment variables. If you don't use any build manager tool such as Maven or Ant you will need to write a script for reading parameters from file and passing them to the command. Example

看看这里。您可以使用命令行参数 ( -D[arg name]=[arg value]) 或环境变量。如果您不使用任何构建管理器工具,例如 Maven 或 Ant,您将需要编写一个脚本来从文件中读取参数并将它们传递给命令。例子