官方网站:
www.liquibase.org
在实际开发中,数据库中的表设计往往不是一成不变的,可能在某个版本中我们需要加入几个字段;或者加入一张表;修改某个字段的约束;添加一些初始数据;等等……
而在个人开发中,这种修改造成的影响尚可以忍受,毕竟自己知道数据库做了哪些更改,或者自己记录了文档方便自己回溯。
但是,在团队开发中,数据库的版本修改造成的影响就比较大了,例如:
团队中某个成员没有同步更新数据库,影响开发进度
由于没有同步更新数据库,某个成员使用了错误的数据
除了数据库版本不一致对开发带来的影响之外,还有一些原因让我们需要 Liquibase:
手工管理数据库版本,繁琐
没有一致的方法管理数据库版本变更
日志不好维护
Liquibase 能够让开发者通过日志的方式记录数据库版本的变更,执行日志中的修改,将数据库更新,或者回滚到某一个版本。Liquibase 有如下特点:
支持几乎所有主流的数据库:MySQL,Oracle,SQLServer 等
支持多开发者的协作维护
日志文件支持多种格式,xml,yaml,json,sql 等
支持多种运行方式,命令行、Maven 插件、Gradle 插件等
本文将通过 maven 插件的方式演示如何使用 Liquibase
🚀初试 Liquibase
初始化项目
使用 IDEA 新建一个 SpringBoot 项目,不使用任何依赖,下面的
pom.xml
文件列出需要用到的依赖和插件
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>2.3.7.RELEASE</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
<version>5.1.49</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.liquibase</groupId>
<artifactId>liquibase-maven-plugin</artifactId>
<version>4.17.2</version>
<configuration>
<promptOnNonLocalDatabase>false</promptOnNonLocalDatabase>
<propertyFile>db/liquibase-mysql.properties</propertyFile>
<rollbackCount>1</rollbackCount>
</configuration>
</plugin>
</plugins>
</build>
编写 application.yml
spring:
application:
name: Liuqibase-demo
datasource:
driver-class-name: com.mysql.jdbc.Driver
username: root
password: 123456
url: jdbc:mysql://localhost:3306/test?serverTimezone=UTC
编写 Liquibase 的配置文件
在资源目录下新建目录db
,在该目录下编写 Liquibase 的配置文件 liquibase-mysql.properties
,主要配置使用的数据库的基本信息
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/test?serverTimezone=UTC
username=root
password=123456
# 变更日志文件的入口
changeLogFile=db/changelog-master.xml
编写变更日志
在资源目录的db
目录下存放数据库相关文件,目录结构如下:
# 资源目录
- 1.0.0 # 数据库 1.0.0 版本
- changelog.xml # 变更日志
- changelog-master.xml # 数据库变更日志主入口文件
- liquibase-mysql.properties # liquibase 配置文件
Liquibase 的 xml 文件的基础模板如下:
<?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"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.8.xsd">
</databaseChangeLog>
在 db
目录下创建数据库变更日志主入口文件:changelog-master.xml
,Liquibase 会根据包含关系层层往下,执行变更集。
<?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"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.8.xsd">
<include file="1.0.0/changelog.xml" relativeToChangelogFile="true"/>
</databaseChangeLog>
在 db\1.0.0
目录下创建变更日志:changelog.xml
<?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"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.8.xsd">
<changeSet id="1.0.0-20221107" author="abc">
<createTable tableName="test_liquibase">
<column name="id" type="varchar(50)" remarks="主键">
<constraints primaryKey="true" />
</column>
<column name="name" type="varchar(50)" remarks="名字"/>
</createTable>
<rollback>
<dropTable tableName="test_liquibase"/>
</rollback>
</changeSet>
</databaseChangeLog>
执行版本变更
❗❗❗ 注意,每次修改了变更日志,都需要执行 maven 的生命周期插件 package
重新打包,将变更日志文件更新到 target
目录中。
使用 maven 插件:liquibase:update
将数据库变更更新到数据库中,执行成功后应该能看到如下语句:
[INFO] BUILD SUCCESS
💡可以使用 liquibase:help
查看插件的使用说明
初次执行成功后,会在指定的数据库中添加两张表databasechangelog
和databasechangeloglock
,这是Liquibase 维护变更日志的。
查看数据库,可以看到我们的添加表的操作成功执行了:
继续修改数据库版本
在 database
目录下创建 2.0.0
目录,创建变更日志:changelog.xml
<?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"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.8.xsd">
<changeSet id="2.0.0-20221107" author="abc">
<addColumn tableName="test_liquibase">
<column name="age" type="int(1)" remarks="年龄"/>
</addColumn>
<rollback>
<dropColumn tableName="test_liquibase" columnName="age"/>
</rollback>
</changeSet>
<changeSet id="insert" author="abc">
<sqlFile path="data.sql" relativeToChangelogFile="true"/>
<rollback>
<sqlFile path="rollback.sql" relativeToChangelogFile="true"/>
</rollback>
</changeSet>
</databaseChangeLog>
在 2.0.0
目录下分别创建 data.sql
和 rollback.sql
文件
insert into test_liquibase values ('11111', 'name', 18);
delete from test_liquibase where id='11111';
❗❗❗ sql 脚本中,文件开头需要编写如下文本,标识作者,id
执行变更,执行 maven 插件 liquibase:update
,查看结果:
mysql> select * from test_liquibase;
+-------+------+------+
| id | name | age |
+-------+------+------+
| 11111 | name | 18 |
+-------+------+------+
1 row in set (0.00 sec)
进行回滚操作
执行一次 maven 插件操作:liquibase:rollback
,根据上面的配置文件的设置,Liquibase 会回滚一个变更集,即将刚才插入的数据删除。
查看结果:
mysql> select * from test_liquibase;
Empty set (0.00 sec)
🚀一些标签的说明
<include>
,包含另一个变更集文件,一般主入口文件使用该标签,去包含变更版本中的变更日志文件
<includeAll>
,包含整个目录中变更集文件
<changeSet>
标签对应一个变更集,即一个变更操作,通常一个变更日志文件中会有该标签或者<include>
。一些常见属性:
id
:唯一,标识该变更集
author
:该变更集的作者
dbms
:执行的数据库
changeSet
的子标签:
<sql>
,编写一段 sql 脚本
<sqlFile>
,引用其他 sql 脚本文件
<createTable>
,创建一张表
<addColumn>
,添加一个字段
<rollback>
,回滚操作
🚀注意点
在实际使用过程中,建议一个变更版本使用一个变更日志主文件,包含其他变更日志,一个变更日志对应一个日志文件。
对于数据的插入操作,建议使用 sql 脚本的方式插入,这样文件结构看起来更清晰。
- database
- 1.0.0
- data.sql
- XxxChangeSet1.xml
- XxxChangeSet2.xml
- changelog.xml
- changelog-master.xml
liquibase 的 maven 插件的使用说明,可以使用其提供的插件:liquibase:help
进行查看
Liquibase 可以帮助我们管理数据库版本,使得数据库版本能够与应用程序版本一致,便于开发维护。
本文介绍了 Liquibase 的简单用法,更多用法还请参考官网自行学习。