1. Введение
В этом руководстве мы рассмотрим ключевые концепции Flyway и то, как мы можем использовать эту структуру для надежного и простого непрерывного изменения схемы базы данных нашего приложения. Кроме того, мы представим пример управления базой данных H2 в памяти с помощью подключаемого модуля Maven Flyway.
Flyway обновляет базу данных с одной версии на другую с помощью миграции. Мы можем писать миграции либо на SQL с синтаксисом, специфичным для базы данных, либо на Java для расширенных преобразований базы данных.
Миграции могут быть версионными или повторяемыми. Первый имеет уникальную версию и применяется ровно один раз. Последний не имеет версии. Вместо этого они (повторно) применяются каждый раз, когда изменяется их контрольная сумма.
В рамках одного прогона миграции повторяемые миграции всегда применяются последними после выполнения ожидающих версий миграций. Повторяемые миграции применяются в порядке их описания. Для одной миграции все операторы выполняются в рамках одной транзакции базы данных.
В этом руководстве мы в основном сосредоточимся на том, как мы используем подключаемый модуль Maven для выполнения миграции базы данных.
2. Плагин Flyway Maven
Чтобы установить плагин Flyway Maven, давайте добавим следующее определение плагина в наш pom.xml:
<plugin>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-maven-plugin</artifactId>
<version>8.0.0</version>
</plugin>
Последняя версия плагина доступна на Maven Central .
Мы можем настроить этот плагин Maven четырьмя различными способами. В следующих разделах мы рассмотрим каждый из этих вариантов.
Пожалуйста, обратитесь к документации , чтобы получить список всех настраиваемых свойств.
2.1. Конфигурация плагина
Мы можем настроить плагин напрямую с помощью тега <configuration>
в определении плагина нашего pom.xml:
<plugin>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-maven-plugin</artifactId>
<version>8.0.0</version>
<configuration>
<user>databaseUser</user>
<password>databasePassword</password>
<schemas>
<schema>schemaName</schema>
</schemas>
...
</configuration>
</plugin>
2.2. Мейвен Свойства
Мы также можем настроить плагин, указав настраиваемые свойства в качестве свойств
Maven в нашем pom:
<project>
...
<properties>
<flyway.user>databaseUser</flyway.user>
<flyway.password>databasePassword</flyway.password>
<flyway.schemas>schemaName</flyway.schemas>
...
</properties>
...
</project>
2.3. Внешний файл конфигурации
Другой вариант — указать конфигурацию плагина в отдельном файле .conf :
flyway.user=databaseUser
flyway.password=databasePassword
flyway.schemas=schemaName
...
Имя файла конфигурации по умолчанию — flyway.conf, и по умолчанию он загружает файлы конфигурации из:
- installDir/conf/flyway.conf
- userhome/flyway.conf
- рабочийDir/flyway.conf
Кодировка задается свойством flyway.encoding
( по умолчанию UTF-8
).
Если мы используем любое другое имя (например , customConfig.conf
) в качестве файла конфигурации, то мы должны указать это явно при вызове команды Maven:
$ mvn -Dflyway.configFiles=customConfig.conf
2.4. Свойства системы
Наконец, все свойства конфигурации также можно указать как системные свойства при вызове Maven в командной строке:
$ mvn -Dflyway.user=databaseUser -Dflyway.password=databasePassword
-Dflyway.schemas=schemaName
Ниже приведен порядок приоритета, когда конфигурация указана более чем одним способом:
- Свойства системы
- Внешний файл конфигурации
- Свойства Maven
- Конфигурация плагина
3. Пример миграции
В этом разделе мы рассмотрим необходимые шаги для переноса схемы базы данных в базу данных H2 в памяти с помощью подключаемого модуля Maven. Мы используем внешний файл для настройки Flyway.
3.1. Обновить POM
Во-первых, давайте добавим H2 в качестве зависимости:
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.4.196</version>
</dependency>
Опять же, мы можем проверить последнюю версию драйвера, доступную на Maven Central . Мы также добавляем плагин Flyway, как объяснялось ранее.
3.2. Настройте Flyway с помощью внешнего файла
Затем мы создаем myFlywayConfig.conf
в $PROJECT_ROOT
со следующим содержимым:
flyway.user=databaseUser
flyway.password=databasePassword
flyway.schemas=app-db
flyway.url=jdbc:h2:mem:DATABASE
flyway.locations=filesystem:db/migration
В приведенной выше конфигурации указано, что наши сценарии миграции находятся в каталоге db/migration .
Он подключается к экземпляру H2 в памяти, используя databaseUser
и databasePassword
.
Схема базы данных приложения — app-db
.
Разумеется, мы заменяем flyway.user, flyway.password
и flyway.url
на собственное имя пользователя базы данных, пароль базы данных и URL-адрес базы данных соответственно.
3.3. Определить первую миграцию
Flyway придерживается следующего соглашения об именах для сценариев миграции:
<префикс><версия>__<описание>.sql
Где:
<Prefix>
— префикс по умолчанию —V
, который мы можем изменить в приведенном выше файле конфигурации, используя свойствоflyway.sqlMigrationPrefix
.<Версия>
— номер версии миграции. Основные и дополнительные версии могут быть разделенысимволом подчеркивания
. Версия миграции всегда должна начинаться с 1.<Description>
— текстовое описание миграции. Двойное подчеркивание отделяет описание от номеров версий.
Пример: V1_1_0__my_first_migration.sql
Итак, давайте создадим каталог db/migration
в $PROJECT_ROOT
со сценарием миграции с именем V1_0__create_employee_schema.sql
, содержащим инструкции SQL для создания таблицы сотрудников:
CREATE TABLE IF NOT EXISTS `employee` (
`id` int NOT NULL AUTO_INCREMENT PRIMARY KEY,
`name` varchar(20),
`email` varchar(50),
`date_of_birth` timestamp
)ENGINE=InnoDB DEFAULT CHARSET=UTF8;
3.4. Выполнение миграции
Затем мы вызываем следующую команду Maven из $PROJECT_ROOT
для выполнения миграции базы данных:
$ mvn clean flyway:migrate -Dflyway.configFiles=myFlywayConfig.conf
Это должно привести к нашей первой успешной миграции.
Схема базы данных теперь должна выглядеть так:
employee:
+----+------+-------+---------------+
| id | name | email | date_of_birth |
+----+------+-------+---------------+
Мы можем повторить этапы определения и выполнения, чтобы выполнить больше миграций.
3.5. Определение и выполнение второй миграции
Давайте посмотрим, как выглядит вторая миграция, создав второй файл миграции с именем V2_0_create_department_schema.sql
, содержащий следующие два запроса:
CREATE TABLE IF NOT EXISTS `department` (
`id` int NOT NULL AUTO_INCREMENT PRIMARY KEY,
`name` varchar(20)
)ENGINE=InnoDB DEFAULT CHARSET=UTF8;
ALTER TABLE `employee` ADD `dept_id` int AFTER `email`;
Затем мы выполним аналогичную миграцию, как в первый раз.
Теперь наша схема базы данных изменилась, чтобы добавить новый столбец для сотрудника
и новую таблицу:
employee:
+----+------+-------+---------+---------------+
| id | name | email | dept_id | date_of_birth |
+----+------+-------+---------+---------------+
department:
+----+------+
| id | name |
+----+------+
Наконец, мы можем убедиться, что обе миграции действительно прошли успешно, вызвав следующую команду Maven:
$ mvn flyway:info -Dflyway.configFiles=myFlywayConfig.conf
4. Создавайте версионные миграции в IntelliJ IDEA
Написание миграций вручную занимает много времени; вместо этого мы можем генерировать их на основе наших сущностей JPA. Мы можем добиться этого, используя плагин для IntelliJ IDEA под названием JPA Buddy .
Чтобы сгенерировать дифференциальную миграцию версий, просто установите подключаемый модуль и вызовите действие из панели JPA Structure.
Мы просто выбираем, какой источник мы хотим сравнить (база данных или объекты JPA), с какой целью (база данных или моментальный снимок модели данных). Затем JPA Buddy создаст миграцию , как показано на анимации:
Еще одним преимуществом JPA Buddy является возможность определять сопоставления между типами Java и баз данных. Кроме того, он корректно работает с пользовательскими типами Hibernate и конвертерами JPA.
5. Отключение Flyway в Spring Boot
Иногда нам может понадобиться отключить миграцию Flyway при определенных обстоятельствах .
Например, обычной практикой является создание схемы базы данных на основе сущностей во время тестов. В такой ситуации мы можем отключить Flyway под тестовым
профилем.
Давайте посмотрим, насколько это просто в Spring Boot .
5.1. Весенняя загрузка 1.x
Все, что нам нужно сделать, это установить свойство flyway.enabled
в нашем файле application-test.properties
:
flyway.enabled=false
5.2. Весенняя загрузка 2.x
В более поздних версиях Spring Boot это свойство было изменено на spring.flyway.enabled
:
spring.flyway.enabled=false
5.3. Empty FlywayMigrationСтратегия
Если мы хотим только отключить автоматическую миграцию Flyway при запуске, но при этом иметь возможность инициировать миграцию вручную , то использование описанных выше свойств не является хорошим выбором.
Это потому, что в такой ситуации Spring Boot больше не будет автоматически настраивать bean- компонент Flyway
. Следовательно, нам придется предоставлять его самостоятельно, что не очень удобно.
Поэтому, если это наш вариант использования, мы можем оставить Flyway включенным и реализовать пустую FlywayMigrationStrategy
:
@Configuration
public class EmptyMigrationStrategyConfig {
@Bean
public FlywayMigrationStrategy flywayMigrationStrategy() {
return flyway -> {
// do nothing
};
}
}
Это эффективно отключит миграцию Flyway при запуске приложения .
Однако мы по-прежнему сможем запустить миграцию вручную:
@RunWith(SpringRunner.class)
@SpringBootTest
public class ManualFlywayMigrationIntegrationTest {
@Autowired
private Flyway flyway;
@Test
public void skipAutomaticAndTriggerManualFlywayMigration() {
flyway.migrate();
}
}
6. Как работает пролетный путь
Чтобы отслеживать, какие миграции мы уже применили и когда, он добавляет в нашу схему специальную учетную таблицу. Эта таблица метаданных также отслеживает контрольные суммы миграции и ее успешность.
Платформа выполняет следующие шаги, чтобы приспособиться к меняющимся схемам базы данных:
- Он проверяет схему базы данных, чтобы найти ее таблицу метаданных (
SCHEMA_VERSION
по умолчанию). Если таблица метаданных не существует, она будет создана. - Он сканирует путь к классам приложения на наличие доступных миграций.
- Он сравнивает миграции с таблицей метаданных. Если номер версии ниже или равен номеру версии, помеченной как текущая, он игнорируется.
- Он помечает все оставшиеся миграции как ожидающие миграции. Они сортируются по номеру версии и выполняются по порядку.
- По мере применения каждой миграции таблица метаданных обновляется соответствующим образом.
7. Команды
Flyway поддерживает следующие основные команды для управления миграцией базы данных:
Информация
: выводит текущий статус/версию схемы базы данных. Он печатает, какие миграции ожидаются, какие миграции были применены, статус примененных миграций и когда они были применены.Migrate
: переносит схему базы данных в текущую версию. Он сканирует путь к классам на наличие доступных миграций и применяет ожидающие миграции.Базовый уровень
: базовый уровень существующей базы данных, исключая все миграции, включаяbaselineVersion
. Baseline помогает начать работу с Flyway в существующей базе данных. После этого новые миграции можно применять в обычном режиме.Validate
: проверяет текущую схему базы данных на соответствие доступным миграциям.Repair
: Восстанавливает таблицу метаданных.Очистить
: удаляет все объекты в настроенной схеме. Конечно, мы никогда не должны использоватьclean
в какой-либо производственной базе данных.
8. Заключение
В этой статье мы узнали, как работает Flyway и как мы можем использовать эту структуру для надежной реконструкции базы данных нашего приложения.
Код, сопровождающий эту статью, доступен на GitHub .