Подтвердить что ты не робот

Запуск linibase в Java-коде

По какой-то причине нет документации по запуску Liquibase внутри Java-кода. Я хочу генерировать таблицы для модульных тестов.

Как я могу запустить его непосредственно в Java?

например.

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

Ответ 1

Это должно быть что-то вроде (взято из источника 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 в зависимости от того, как должны быть найдены ваши файлы изменений.

Ответ 2

Я нашел способ добиться настройки базы данных с помощью Maven или Java. В приведенном выше примере используется FileSystemResourceAccessor(), который, к сожалению, делает так, что если вы развернете приложение, которому нужно настроить базу данных из самого jar файла, вам придется извлечь jar файл в виде zip файла в качестве обходного пути, так как эти liquibase файлы существуют только в банке. Это означает, что ваша банка в конечном итоге не переносима, и вы должны иметь 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.

<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
            }
        }
    }
}