【问题标题】:Running liquibase within Java code在 Java 代码中运行 liquibase
【发布时间】:2012-05-24 02:37:56
【问题描述】:

由于某种原因,没有关于在 Java 代码中运行 liquibase 的文档。我想为单元测试生成表格。

如何直接在 Java 中运行它?

例如

Liquibase liquibase = new Liquibase()
liquibase.runUpdates() ?

【问题讨论】:

标签: java liquibase


【解决方案1】:

您可以在测试中使用 h2-database 进行练习(路径“db/changelog.xml”为 main/resources/db/changelog.xml):

import liquibase.Contexts;
import liquibase.Liquibase;
import liquibase.database.Database;
import liquibase.database.DatabaseFactory;
import liquibase.database.jvm.JdbcConnection;
import liquibase.exception.LiquibaseException;
import liquibase.resource.ClassLoaderResourceAccessor;
import org.junit.jupiter.api.Test;

import java.sql.DriverManager;
import java.sql.SQLException;

public class LiquidBaseTest {

    @Test
    public void testExecuteLiquidBaseScripts() throws SQLException, LiquibaseException {
        java.sql.Connection connection = DriverManager.getConnection("jdbc:h2:mem:");

        try {
            Database database = DatabaseFactory.getInstance().findCorrectDatabaseImplementation(new JdbcConnection(connection));
            Liquibase liquibase = new Liquibase("db/changelog.xml", new ClassLoaderResourceAccessor(), database);
            liquibase.update(new Contexts());
        } finally {
            if (connection != null) {
                connection.rollback();
                connection.close();
            }
        }
    }

}

【讨论】:

    【解决方案2】:

    我找到了一种方法来实现使用或者 maven 或Java 设置数据库。上面的示例使用了FileSystemResourceAccessor(),不幸的是,如果您部署需要从 jar 本身设置数据库的应用程序,那么您最终必须将 jar 作为 zipextract作为一种解决方法,因为这些 liquibase 文件仅存在于 jar 中。这意味着您的 jar 最终是不可移植的,并且您必须在要设置数据库的任何位置拥有 maven

    使用这个结构:

    src/main/resources/liquibase/db.changelog-master.xml src/main/resources/liquibase/changelogs/...

    您的数据库变更日志主文件可能如下所示:

    <?xml version="1.0" encoding="UTF-8"?>
    <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 http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.1.xsd
        http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd">
    
        <!-- <includeAll path="src/main/resources/liquibase/changelogs"/> -->
        <include file="changelogs/my-date.1.sql" relativeToChangelogFile="true"/>
    </databaseChangeLog>
    

    您可以将此部分用于您的 pom.xml,以确保 mvn install 也将设置您的 liquibase DB。

    <plugin>
       <groupId>org.liquibase</groupId>
       <artifactId>liquibase-maven-plugin</artifactId>
       <version>3.5.1</version>
       <configuration>
          <changeLogFile>liquibase/db.changelog-master.xml</changeLogFile>
          <driver>org.postgresql.Driver</driver>
          <url>${jdbc.url}</url>
          <username>${jdbc.username}</username>
          <password>${jdbc.password}</password>
       </configuration>
       <executions>
          <execution>
             <phase>process-resources</phase>
             <goals>
                <goal>update</goal>
             </goals>
          </execution>
       </executions>
    </plugin>
    

    使用ClassLoaderResourceAccessor() 而不是FileSystemResourceAccessor()

    public static void runLiquibase() {
    
        Liquibase liquibase = null;
        Connection c = null;
        try {
            c = DriverManager.getConnection(DataSources.PROPERTIES.getProperty("jdbc.url"),
                    DataSources.PROPERTIES.getProperty("jdbc.username"),
                    DataSources.PROPERTIES.getProperty("jdbc.password"));
    
            Database database = DatabaseFactory.getInstance().findCorrectDatabaseImplementation(new JdbcConnection(c));
            log.info(DataSources.CHANGELOG_MASTER);
            liquibase = new Liquibase(DataSources.CHANGELOG_MASTER, new ClassLoaderResourceAccessor(), database);
            liquibase.update("main");
        } catch (SQLException | LiquibaseException e) {
            e.printStackTrace();
            throw new NoSuchElementException(e.getMessage());
        } finally {
            if (c != null) {
                try {
                    c.rollback();
                    c.close();
                } catch (SQLException e) {
                    //nothing to do
                }
            }
        }
    }
    

    【讨论】:

    • 您可能需要完整路径:&lt;changeLogFile&gt;liquibase/db.changelog-master.xml&lt;/changeLogFile&gt; 因此:src/main/resources/liquibase/db.changelog-master.xml
    【解决方案3】:

    它应该类似于(取自 liquibase.integration.spring.SpringLiquibase 源):

    java.sql.Connection c = YOUR_CONNECTION;
    Liquibase liquibase = null;
    try {
        Database database = DatabaseFactory.getInstance().findCorrectDatabaseImplementation(new JdbcConnection(c))
        liquibase = new Liquibase(YOUR_CHANGELOG, new FileSystemResourceAccessor(), database);
        liquibase.update();
    } catch (SQLException e) {
        throw new DatabaseException(e);
    } finally {
        if (c != null) {
            try {
                c.rollback();
                c.close();
            } catch (SQLException e) {
                //nothing to do
            }
        }
    }
    

    ResourceAccessor 有多种实现方式,具体取决于您应该如何找到更改日志文件。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-08-12
    • 2011-01-03
    • 1970-01-01
    • 2019-03-14
    • 1970-01-01
    • 2011-03-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多