Flyway для Java: полное руководство с примерами

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Введение в Flyway: что это и зачем нужно

Flyway — это библиотека для управления версиями и миграциями баз данных (Database Migration Tool). В современной разработке программного обеспечения, особенно в командной работе и при использовании методологий CI/CD, возникает критическая необходимость синхронизировать структуру базы данных между разработчиками, тестовыми и продуктивными средами. Flyway решает эту задачу, позволяя описывать изменения схемы БД (создание таблиц, добавление колонок, индексов, триггеров и т.д.) в виде последовательных, версионированных SQL-скриптов или Java-классов.

Основная концепция Flyway проста: каждая миграция имеет уникальный номер версии (например, V1, V2, V3) и выполняется ровно один раз. Библиотека отслеживает, какие миграции уже были применены к конкретной базе данных, используя специальную таблицу (по умолчанию flyway_schema_history). Это гарантирует идемпотентность и воспроизводимость состояния базы данных.

Зачем использовать Flyway?

  • Версионирование схемы: Каждое изменение базы данных — это отдельная версия, которую можно откатить или применить.
  • Автоматизация: Интеграция с Maven, Gradle, Spring Boot и CI/CD пайплайнами.
  • Контроль целостности: Flyway проверяет контрольные суммы миграций, предотвращая случайные изменения уже выполненных скриптов.
  • Простота: Для большинства задач достаточно написать обычный SQL-скрипт.

Установка Flyway для Java

Flyway не устанавливается через pip или npm, так как это Java-библиотека. Существует несколько способов добавить её в проект:

1. Maven (pom.xml)

<dependency>
    <groupId>org.flywaydb</groupId>
    <artifactId>flyway-core</artifactId>
    <version>9.22.3</version> <!-- Актуальная версия на момент написания -->
</dependency>

<!-- Драйвер для вашей БД, например PostgreSQL -->
<dependency>
    <groupId>org.postgresql</groupId>
    <artifactId>postgresql</artifactId>
    <version>42.7.1</version>
</dependency>

2. Gradle (build.gradle)

implementation 'org.flywaydb:flyway-core:9.22.3'
implementation 'org.postgresql:postgresql:42.7.1'

3. Плагин Maven (для запуска из командной строки)

<plugin>
    <groupId>org.flywaydb</groupId>
    <artifactId>flyway-maven-plugin</artifactId>
    <version>9.22.3</version>
    <configuration>
        <url>jdbc:postgresql://localhost:5432/mydb</url>
        <user>myuser</user>
        <password>mypassword</password>
    </configuration>
</plugin>

4. Spring Boot (автоматическая конфигурация)

Если вы используете Spring Boot, достаточно добавить зависимость и настроить параметры в application.properties:

spring.flyway.enabled=true
spring.flyway.locations=classpath:db/migration
spring.datasource.url=jdbc:postgresql://localhost:5432/mydb
spring.datasource.username=myuser
spring.datasource.password=mypassword

Быстрый старт с примером кода

Рассмотрим минимальный пример использования Flyway в Java-приложении для создания таблицы users.

Шаг 1: Создайте структуру директорий для миграций

По умолчанию Flyway ищет SQL-скрипты в папке db/migration в classpath (например, src/main/resources/db/migration).

Шаг 2: Создайте файл миграции

Создайте файл V1__Create_users_table.sql в этой папке:

CREATE TABLE users (
    id SERIAL PRIMARY KEY,
    username VARCHAR(50) NOT NULL UNIQUE,
    email VARCHAR(100) NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

Шаг 3: Напишите Java-код для запуска миграции

import org.flywaydb.core.Flyway;

public class FlywayExample {
    public static void main(String[] args) {
        // Создаем объект Flyway и настраиваем подключение к БД
        Flyway flyway = Flyway.configure()
                .dataSource("jdbc:postgresql://localhost:5432/mydb", "myuser", "mypassword")
                .load();

        // Запускаем миграцию
        flyway.migrate();

        System.out.println("Миграция успешно выполнена!");
    }
}

Результат: После запуска этого кода в базе данных появится таблица users и служебная таблица flyway_schema_history, в которой будет запись о выполненной миграции V1.

Основные методы/функции Flyway (Java API)

Flyway предоставляет богатый API для управления миграциями. Рассмотрим 10 ключевых методов.

1. configure()

Что делает: Создает конфигуратор FluentConfiguration для настройки Flyway перед загрузкой. Это отправная точка для всех настроек.

Параметры: Не принимает параметров. Возвращает FluentConfiguration.

Пример:

Flyway flyway = Flyway.configure()
        .dataSource(url, user, password)
        .locations("classpath:db/migration")
        .load();

2. dataSource(String url, String user, String password)

Что делает: Устанавливает подключение к базе данных. Можно передать как строки, так и готовый javax.sql.DataSource.

Параметры:

  • url — JDBC URL базы данных (например, jdbc:postgresql://localhost:5432/mydb).
  • user — имя пользователя.
  • password — пароль.

Пример:

Flyway flyway = Flyway.configure()
        .dataSource("jdbc:mysql://localhost:3306/mydb", "root", "secret")
        .load();

3. locations(String... locations)

Что делает: Указывает пути, где Flyway будет искать файлы миграций. По умолчанию — classpath:db/migration.

Параметры: Один или несколько строковых путей. Можно использовать префиксы classpath: и filesystem:.

Пример:

Flyway flyway = Flyway.configure()
        .locations("classpath:db/migration", "filesystem:/opt/migrations")
        .load();

4. migrate()

Что делает: Основной метод. Применяет все ожидающие миграции к базе данных. Возвращает объект MigrateResult, содержащий информацию о количестве выполненных миграций и времени выполнения.

Параметры: Нет.

Пример:

MigrateResult result = flyway.migrate();
System.out.println("Выполнено миграций: " + result.migrationsExecuted);

5. validate()

Что делает: Проверяет, что все примененные миграции соответствуют их текущим файлам (по контрольной сумме). Если какая-то миграция была изменена после выполнения, метод выбросит исключение FlywayException.

Параметры: Нет.

Пример:

try {
    flyway.validate();
    System.out.println("Валидация пройдена успешно.");
} catch (FlywayException e) {
    System.err.println("Ошибка валидации: " + e.getMessage());
}

6. info()

Что делает: Возвращает информацию о состоянии миграций: какие применены, какие ожидают выполнения, их версии и описания. Возвращает объект MigrationInfoService.

Параметры: Нет.

Пример:

MigrationInfoService info = flyway.info();
for (MigrationInfo migrationInfo : info.all()) {
    System.out.println("Версия: " + migrationInfo.getVersion() +
                       ", Описание: " + migrationInfo.getDescription() +
                       ", Статус: " + migrationInfo.getState());
}

7. clean()

Что делает: Полностью очищает базу данных: удаляет все объекты (таблицы, представления, процедуры) и сбрасывает таблицу истории миграций. Осторожно! Этот метод необратимо уничтожает данные.

Параметры: Нет.

Пример:

// Используется обычно в тестовых средах
flyway.clean();
System.out.println("База данных очищена.");

8. baseline()

Что делает: Создает базовую линию (baseline) для существующей базы данных. Это полезно, когда вы начинаете использовать Flyway на уже существующем проекте с живой базой данных. Метод помечает текущее состояние БД как версию 1 (или указанную вами), не применяя никаких миграций.

Параметры:

  • baselineVersion (опционально) — версия, с которой начинается отсчет.
  • baselineDescription (опционально) — описание базовой линии.

Пример:

Flyway flyway = Flyway.configure()
        .dataSource(url, user, password)
        .baselineVersion("1")
        .baselineDescription("Initial state of production DB")
        .load();
flyway.baseline();

9. repair()

Что делает: Исправляет проблемы в таблице истории миграций. Например, удаляет записи о неудачных миграциях или исправляет контрольные суммы, если вы намеренно изменили уже выполненный скрипт (не рекомендуется, но бывает нужно).

Параметры: Нет.

Пример:

try {
    flyway.repair();
    System.out.println("Таблица истории восстановлена.");
} catch (FlywayException e) {
    System.err.println("Ошибка восстановления: " + e.getMessage());
}

10. undo() (доступно в Flyway Teams/Enterprise)

Что делает: Откатывает последнюю примененную миграцию. Для этого необходимо создать специальный файл отката (например, U1__Create_users_table.sql). Важно: Этот метод недоступен в бесплатной версии Flyway Community Edition.

Параметры: Нет.

Пример:

// Требует файл U1__Create_users_table.sql с DROP TABLE users;
flyway.undo();
System.out.println("Последняя миграция откачена.");

Реальный практический пример использования

Рассмотрим сценарий разработки веб-приложения для интернет-магазина. Нам нужно управлять эволюцией схемы базы данных.

Задача: Добавить таблицу products, затем изменить её, добавив колонку price, и наконец создать индекс.

Структура миграций:

Рекомендаций