1. Обзор
В этом кратком руководстве мы будем использовать Liquibase для развития схемы базы данных веб-приложения Java.
Сначала мы рассмотрим общее Java-приложение, а также подробно рассмотрим некоторые интересные варианты, доступные для Spring и Hibernate.
Вкратце, ядром использования Liquibase является файл changeLog ,
XML-файл, в котором отслеживаются все изменения, которые необходимо выполнить для обновления БД.
Давайте начнем с зависимости Maven, которую нам нужно добавить в наш pom.xml
:
<dependency>
<groupId>org.liquibase</groupId>
<artifactId>liquibase-core</artifactId>
<version>3.4.1</version>
</dependency>
Мы также можем проверить, есть ли более новая версия liquibase-core здесь .
2. Журнал изменений базы данных
Теперь давайте взглянем на простой файл журнала изменений
.
Этот только добавляет столбец « адрес
» в таблицу « пользователи
»:
<databaseChangeLog
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog-ext
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd
http://www.liquibase.org/xml/ns/dbchangelog
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.4.xsd">
<changeSet author="John" id="someUniqueId">
<addColumn tableName="users">
<column name="address" type="varchar(255)" />
</addColumn>
</changeSet>
</databaseChangeLog>
Обратите внимание, как набор изменений идентифицируется идентификатором
и автором
, чтобы убедиться, что он может быть однозначно идентифицирован и применен только один раз.
Давайте теперь посмотрим, как связать это с нашим приложением и убедиться, что оно запускается при запуске приложения.
3. Запустите Liquibase с помощью Spring Bean
Наш первый вариант запуска изменений при запуске приложения — через Spring bean.
Конечно, есть много других способов, но это хороший и простой способ, если мы имеем дело с приложением Spring:
@Bean
public SpringLiquibase liquibase() {
SpringLiquibase liquibase = new SpringLiquibase();
liquibase.setChangeLog("classpath:liquibase-changeLog.xml");
liquibase.setDataSource(dataSource());
return liquibase;
}
Обратите внимание, как мы указываем на действительный файл журнала изменений
, который должен существовать в пути к классам.
4. Используйте Liquibase с Spring Boot
Если мы используем Spring Boot , нет необходимости определять bean
-компонент для Liquibase, но нам все равно нужно убедиться, что мы добавили зависимость от liquibase-core.
Затем все, что нам нужно, это поместить наш журнал изменений в db/changelog/db.changelog-master.yaml , и миграция Liquibase будет выполняться автоматически при запуске.
Мы можем изменить файл журнала изменений по умолчанию, используя свойство liquibase.change-log
:
liquibase.change-log=classpath:liquibase-changeLog.xml
5. Отключить Liquibase в Spring Boot
Иногда нам может потребоваться отключить выполнение миграции Liquibase при запуске.
Самый простой вариант, который у нас есть, — использовать свойство spring.liquibase.enabled
. Таким образом, вся оставшаяся конфигурация Liquibase останется нетронутой.
Вот пример для Spring Boot 2:
spring.liquibase.enabled=false
Для Spring Boot 1.x нам нужно использовать свойство liquibase.enabled
:
liquibase.enabled=false
6. Создайте журнал изменений
с помощью плагина Maven.
Вместо того, чтобы писать файл журнала изменений вручную, мы можем использовать плагин Liquibase
Maven для его создания и сэкономить нам много работы.
6.1. Конфигурация плагина
Вот изменения в нашем pom.xml
:
<dependency>
<groupId>org.liquibase</groupId>
<artifactId>liquibase-maven-plugin</artifactId>
<version>3.4.1</version>
</dependency>
...
<plugins>
<plugin>
<groupId>org.liquibase</groupId>
<artifactId>liquibase-maven-plugin</artifactId>
<version>3.4.1</version>
<configuration>
<propertyFile>src/main/resources/liquibase.properties</propertyFile>
</configuration>
</plugin>
</plugins>
6.2. Создание журнала изменений
из существующей базы данных
Мы можем использовать плагин для создания журнала изменений из существующей базы данных:
mvn liquibase:generateChangeLog
Вот свойства ликвибазы
:
url=jdbc:mysql://localhost:3306/oauth_reddit
username=tutorialuser
password=tutorialmy5ql
driver=com.mysql.jdbc.Driver
outputChangeLogFile=src/main/resources/liquibase-outputChangeLog.xml
Конечным результатом является файл журнала изменений
, который мы можем использовать либо для создания начальной схемы БД, либо для заполнения данными.
Вот как это будет выглядеть:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<databaseChangeLog ...>
<changeSet author="John (generated)" id="1439225004329-1">
<createTable tableName="APP_USER">
<column autoIncrement="true" name="id" type="BIGINT">
<constraints primaryKey="true"/>
</column>
<column name="accessToken" type="VARCHAR(255)"/>
<column name="needCaptcha" type="BIT(1)">
<constraints nullable="false"/>
</column>
<column name="password" type="VARCHAR(255)"/>
<column name="refreshToken" type="VARCHAR(255)"/>
<column name="tokenExpiration" type="datetime"/>
<column name="username" type="VARCHAR(255)">
<constraints nullable="false"/>
</column>
<column name="preference_id" type="BIGINT"/>
<column name="address" type="VARCHAR(255)"/>
</createTable>
</changeSet>
...
</databaseChangeLog>
6.3. Создайте журнал изменений
из различий между двумя базами данных
Мы можем использовать плагин для создания файла журнала изменений
из различий между двумя существующими базами данных (например, разработка и производство):
mvn liquibase:diff
Вот свойства:
changeLogFile=src/main/resources/liquibase-changeLog.xml
url=jdbc:mysql://localhost:3306/oauth_reddit
username=tutorialuser
password=tutorialmy5ql
driver=com.mysql.jdbc.Driver
referenceUrl=jdbc:h2:mem:oauth_reddit
diffChangeLogFile=src/main/resources/liquibase-diff-changeLog.xml
referenceDriver=org.h2.Driver
referenceUsername=sa
referencePassword=
А вот фрагмент сгенерированного журнала изменений
:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<databaseChangeLog ...>
<changeSet author="John" id="1439227853089-1">
<dropColumn columnName="address" tableName="APP_USER"/>
</changeSet>
</databaseChangeLog>
Это очень мощный способ развития нашей БД, например, позволяя Hibernate автоматически генерировать новую схему для разработки, а затем использовать ее в качестве ориентира для старой схемы.
7. Используйте плагин Liquibase Hibernate
В случае, если наше приложение использует Hibernate, мы рассмотрим очень полезный способ создания журнала изменений , которым является плагин liquibase -
hibernate
. ``
7.1. Конфигурация плагина
Во-первых, давайте настроим новый плагин и используем правильные зависимости:
<plugins>
<plugin>
<groupId>org.liquibase</groupId>
<artifactId>liquibase-maven-plugin</artifactId>
<version>3.4.1</version>
<configuration>
<propertyFile>src/main/resources/liquibase.properties</propertyFile>
</configuration>
<dependencies>
<dependency>
<groupId>org.liquibase.ext</groupId>
<artifactId>liquibase-hibernate4</artifactId>
<version>3.5</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>4.1.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>1.7.3.RELEASE</version>
</dependency>
</dependencies>
</plugin>
</plugins>
7.2. Создание журнала изменений
из различий между базой данных и сущностями персистентности
Мы можем использовать этот плагин для создания файла журнала изменений
на основе различий между существующей базой данных (например, рабочей) и нашими новыми сущностями постоянства.
Таким образом, для простоты после изменения объекта мы можем просто сгенерировать изменения для старой схемы БД, получив чистый и мощный способ развития нашей схемы в производственной среде.
Вот свойства ликвибазы
:
changeLogFile=classpath:liquibase-changeLog.xml
url=jdbc:mysql://localhost:3306/oauth_reddit
username=tutorialuser
password=tutorialmy5ql
driver=com.mysql.jdbc.Driver
referenceUrl=hibernate:spring:org.foreach.persistence.model
?dialect=org.hibernate.dialect.MySQLDialect
diffChangeLogFile=src/main/resources/liquibase-diff-changeLog.xml
Обратите внимание, что referenceUrl
использует сканирование пакетов, поэтому параметр диалекта
является обязательным.
8. Создайте журнал изменений
в IntelliJ IDEA с помощью подключаемого модуля JPA Buddy.
Если мы используем не-Hibernate ORM (например, EclipseLink или OpenJPA) или не хотим добавлять дополнительные зависимости, такие как плагин liquibase-hibernate
, мы можем использовать JPA Buddy . Этот плагин IntelliJ IDEA интегрирует полезные функции Liquibase в IDE.
Чтобы сгенерировать дифференциальный журнал изменений
, мы просто устанавливаем плагин, а затем вызываем действие из панели структуры JPA. Мы выбираем, какой источник мы хотим сравнить (база данных, сущности JPA или моментальный снимок Liquibase) с какой целью (база данных или моментальный снимок Liquibase).
JPA Buddy сгенерирует журнал изменений
, как показано на анимации ниже :
Еще одним преимуществом JPA Buddy по сравнению с подключаемым модулем liquibase-hibernate
является возможность переопределения сопоставлений по умолчанию между типами Java и баз данных. Кроме того, он корректно работает с пользовательскими типами Hibernate и конвертерами JPA.
9. Заключение
В этой статье мы проиллюстрировали несколько способов использования Liquibase и нашли безопасный и зрелый способ развития и рефакторинга схемы БД приложения Java.
Реализация всех этих примеров и фрагментов кода доступна на GitHub .