Liquibase
— это инструмент рефакторинга базы данных с открытым исходным кодом для отслеживания, управления и применения изменений базы данных. Он сохраняет все изменения базы данных (как структуры, так и данных) вchangelog
файл, он удобен для контроля версий, и его цель — предоставить решение, не зависящее от типа базы данных, путем выполнения файлов типа схемы для достижения миграции.
Ликвибаза Особенности
Liquibase имеет следующие особенности:
- Поддержка практически всех основных баз данных, таких как MySQL, PostgreSQL, Oracle, Sql Server, DB2 и т. д.;
- Поддержка совместного обслуживания нескольких разработчиков;
- Файл журнала поддерживает несколько форматов, таких как XML, YAML, JSON, SQL и т. д.;
- Поддержка контекстно-зависимой логики
- Создание документации по изменению базы данных
- Поддерживает несколько режимов запуска, таких как командная строка, интеграция Spring, плагин Maven, плагин Gradle и т. д.
Для получения более подробной информации см.Официальная документация Liquibase
Spring Boot интегрирует Liquibase
добавить зависимости
Поскольку Spring Boot имеет встроенную поддержку интеграции Liquibase, нам нужно только ввести зависимости Liquibase в проект для настройки.
<dependency>
<groupId>org.liquibase</groupId>
<artifactId>liquibase-core</artifactId>
<version>3.6.3</version>
</dependency>
Настроить файл приложения
Настройте файл application.properties или application.yml в пути к классам,
# 启用liquibase
liquibase.enabled=true
# 存储变化的文件(changelog)位置
liquibase.change-log=classpath:sample_change.sql
# 检查存储变化的文件是否存在
liquibase.check-change-log-location=true
# 分环境执行,若在 changelog 文件中设置了对应 context 属性,则只会执行与 dev 对应值的 changeset
liquibase.contexts=dev
# 执行前首先删除数据库,默认 false。若设置为 true,则执行变更前,会先删除目标数据库,请谨慎
liquibase.dropFirst=false
# 执行更新时将回滚 SQL 写入的文件路径
liquibase.rollback-file=
# 如果使用工程已配置的 datasource 数据源,则以下三个数据库连接参数可不配置
## 访问数据库的连接地址
liquibase.url=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8
# 访问数据库的用户名
liquibase.user=test
# 访问数据库的密码
liquibase.password=test
Примечание. При использовании настроенного проекта
datasource
источник данных, затемliquibase.url、liquibase.user
иliquibase.password
Эти три параметра нельзя настроить, а целевым источником данных является настроенный источник данных проекта. Поскольку Spring автоматически получит доступные источники данных для liquibase, подробности см. в этом классе:org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration
.
Напишите файл журнала изменений, в котором хранятся изменения
В настоящее время Liquibase поддерживает файлы журнала изменений в четырех форматах: XML, YAML, JSON и SQL. Для удобства и наглядности файл журнала изменений написан в формате на основе SQL ниже: sample_change.sql
--liquibase formatted sql
--changeset zhouyi:1
-- 创建用户表
CREATE TABLE `user` (
`id` int(20) NOT NULL AUTO_INCREMENT,
`name` varchar(50) NOT NULL,
`age` int(10) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--rollback drop table user;
--changeset zhouyi:2
insert into user(id, name, age) values(1,'张三',29);
insert into user(id, name, age) values(2,'李四',20);
После запуска приложения Spring Boot вы можете увидеть вывод из журнала:
2019-03-27 13:13:16.439 [main] [] INFO liquibase.executor.jvm.JdbcExecutor.info:42 - DELETE FROM test.DATABASECHANGELOGLOCK
2019-03-27 13:13:16.442 [main] [] INFO liquibase.executor.jvm.JdbcExecutor.info:42 - INSERT INTO test.DATABASECHANGELOGLOCK (ID, `LOCKED`) VALUES (1, 0)
2019-03-27 13:13:16.506 [main] [] INFO liquibase.executor.jvm.JdbcExecutor.info:42 - SELECT `LOCKED` FROM test.DATABASECHANGELOGLOCK WHERE ID=1
2019-03-27 13:13:16.586 [main] [] INFO liquibase.lockservice.StandardLockService.info:42 - Successfully acquired change log lock
2019-03-27 13:13:16.697 [main] [] INFO liquibase.changelog.StandardChangeLogHistoryService.info:42 - Creating database history table with name: test.DATABASECHANGELOG
2019-03-27 13:13:16.700 [main] [] INFO liquibase.executor.jvm.JdbcExecutor.info:42 - CREATE TABLE test.DATABASECHANGELOG (ID VARCHAR(255) NOT NULL, AUTHOR VARCHAR(255) NOT NULL, FILENAME VARCHAR(255) NOT NULL, DATEEXECUTED datetime NOT NULL, ORDEREXECUTED INT NOT NULL, EXECTYPE VARCHAR(10) NOT NULL, MD5SUM VARCHAR(35) NULL, `DESCRIPTION` VARCHAR(255) NULL, COMMENTS VARCHAR(255) NULL, TAG VARCHAR(255) NULL, LIQUIBASE VARCHAR(20) NULL, CONTEXTS VARCHAR(255) NULL, LABELS VARCHAR(255) NULL, DEPLOYMENT_ID VARCHAR(10) NULL)
2019-03-27 13:13:17.570 [main] [] INFO liquibase.executor.jvm.JdbcExecutor.info:42 - SELECT COUNT(*) FROM test.DATABASECHANGELOG
2019-03-27 13:13:17.575 [main] [] INFO liquibase.changelog.StandardChangeLogHistoryService.info:42 - Reading from test.DATABASECHANGELOG
2019-03-27 13:13:17.579 [main] [] INFO liquibase.executor.jvm.JdbcExecutor.info:42 - SELECT * FROM test.DATABASECHANGELOG ORDER BY DATEEXECUTED ASC, ORDEREXECUTED ASC
2019-03-27 13:13:17.585 [main] [] INFO liquibase.executor.jvm.JdbcExecutor.info:42 - SELECT COUNT(*) FROM test.DATABASECHANGELOGLOCK
2019-03-27 13:13:17.678 [main] [] INFO liquibase.executor.jvm.JdbcExecutor.info:42 - CREATE TABLE `user` (
`id` int(20) NOT NULL AUTO_INCREMENT,
`name` varchar(50) NOT NULL,
`age` int(10) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
2019-03-27 13:13:17.935 [main] [] INFO liquibase.changelog.ChangeSet.info:42 - Custom SQL executed
2019-03-27 13:13:17.937 [main] [] INFO liquibase.changelog.ChangeSet.info:42 - ChangeSet classpath:sample_change.sql::1::zhouyi ran successfully in 297ms
2019-03-27 13:13:17.938 [main] [] INFO liquibase.executor.jvm.JdbcExecutor.info:42 - SELECT MAX(ORDEREXECUTED) FROM test.DATABASECHANGELOG
Вы можете увидеть изменения из базы данных, при первом запуске добавлены 3 новые таблицы,
вDATABASECHANGELOG
иDATABASECHANGELOGLOCK
Таблица автоматически генерируется Liquibase, аuser
Таблица предназначена для выполнения того, что мы написалиchangeset
После создания набора изменений и выполнения второго набора изменений вставляются две части данных.
Файл журнала изменений в формате SQL
в формате SQLchangelog
Файл использует комментарии SQL в качестве метаданных, чтобы гарантировать, что этот файл распознается Liquibase какchangelog
файл, файл SQL должен начинаться со следующего комментария:
--liquibase formatted sql
набор изменений
в формате SQLchangelog
Следующие комментарии необходимо добавить перед измененным SQL в файле, который выражается какchangeset
Набор изменений:
--changeset author:id attribute1:value1 attribute2:value2 [...]
в предыдущемsample_change.sql
В файле написано дваchangeset
(набор изменений),
набор измененийchangeset
черезauthor + id
способ гарантировать уникальность, как указано вышеzhouyi:1
иzhouyi:2
Две таблицы обновлены.
Набор изменений предоставляет следующие свойства:
Атрибуты | инструкция |
---|---|
stripComments | Установите значение true, чтобы удалить все комментарии в SQL перед выполнением, в противном случае — значение false. Если не установлено, значение по умолчанию равно true |
splitStatements | |
endDelimiter | Разделитель применяется к концу оператора. По умолчанию ";", также можно установить "" |
runAlways | Выполнять наборы изменений при каждом запуске, даже если они были запущены до |
runOnChange | Просматривайте изменения в первый раз и выполняйте изменения каждый раз, когда изменяется набор изменений. |
context | Выполняет изменения, если определенный контекст передается во время выполнения. Любая строка может использоваться в качестве имени контекста и нечувствительна к регистру. |
logicalFilePath | Используется для переопределения имен файлов и путей при создании уникального идентификатора набора изменений. Требуется при перемещении или переименовании журналов изменений. |
labels | Метки — это распространенный метод классификации наборов изменений, наборов похожих контекстов, но работающих противоположным образом. Если вместо определения набора контекстов во время выполнения, а затем определения выражения соответствия в наборе изменений, определите набор тегов в контексте и определите выражение соответствия во время выполнения. |
runInTransaction | Должен ли набор изменений выполняться как одна транзакция (если возможно), значение по умолчанию — true. Обратите внимание, что если для этого свойства задано значение false и возникает ошибка при выполнении раздела набора изменений, содержащего несколько операторов, база данных liquibasedatabasechangeloglock Таблица будет в недопустимом состоянии |
failOnError | Должна ли миграция возвращать ошибку, если при выполнении набора изменений возникает ошибка |
dbms | Тип базы данных, используемой для этого набора изменений. Когда шаг миграции выполняется, он проверяет тип базы данных на соответствие этому свойству, например: oracle, mysql |
logicalFilePath | в базе данныхdatabasechangeloglock Задайте путь к логическому файлу в , а не к физическому местоположению файла sql, в котором выполняется liquibase. |
предварительное условие
Предварительные требования могут быть указаны для каждого набора изменений. В настоящее время поддерживаются только предварительные условия проверки SQL.
--preconditions onFail:HALT onError:HALT
--precondition-sql-check expectedResult:0 SELECT COUNT(*) FROM my_table
операция отката
Набор изменений может включать операторы, применяемые при откате набора изменений. Объявления отката также используют аннотации таблиц.
--rollback SQL STATEMENT
Например, первый набор изменений в файле журнала изменений, написанном ранее:
--changeset zhouyi:1
-- 创建用户表
CREATE TABLE `user` (
`id` int(20) NOT NULL AUTO_INCREMENT,
`name` varchar(50) NOT NULL,
`age` int(10) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--rollback drop table user;
Значение SQL первого изменения заключается в создании новогоuser
таблица, откат SQL означает удаление вновь созданнойuser
поверхность.
Лучшие практики Liquibase
Ниже приведены некоторые рекомендации, которые вы можете применить к своим проектам.
Набор изменений устанавливает только одно изменение
По возможности избегайте внесения нескольких изменений в набор изменений, чтобы избежать автоматической фиксации операторов SQL, которые могут оставить базу данных в непредвиденном состоянии.
как--changeset zhouyi:1
Изменить набор, только создать новыйuser
Таблица, набор изменений не будет изменен позже, если вам нужно изменить, вы можете добавить набор изменений.
ID набора изменений
Выберите метод, который работает для вас. Некоторые люди используют серийные номера, которые начинаются с 1 и являются уникальными в журнале изменений, другие выбирают описательное имя (например:new-address-table
)
Всегда рассчитывайте на откат
Попробуйте написать наборы изменений таким образом, чтобы их можно было откатить, например.--changeset zhouyi:1
Создать новый набор измененийuser
таблица, за которой следует откат SQL,--rollback drop table user;
Добавить комментарии к наборам изменений
Попробуйте добавить комментарий к каждой записи набора изменений, например.-- 创建用户表
Процесс использования разработчика
- Используя вашу любимую IDE или редактор, создайте новый локальный набор изменений с изменениями;
- Запустите Liquibase, чтобы выполнить новый набор изменений (это проверит код SQL);
- Внесите соответствующие изменения в код приложения (например, Java-код);
- Тесты проверяют новый код приложения и изменения в базе данных;
- Зафиксируйте наборы изменений и код приложения.