1.概述
在我们之前的文章中,我们将Liquibase显示为管理数据库模式和数据的工具。
在本文中,我们将更多地介绍回滚功能 - 以及我们如何撤消Liquibase操作。
当然,这是任何生产级系统的关键特征。
2. Liquibase迁移的类别
有两类Liquibase操作,导致不同代的回滚语句:
- automatic,其中迁移可以确定性地生成回滚所需的步骤
- manual,我们需要发出回滚命令,因为迁移指令不能用于确定性地识别语句
例如,回滚“create table”语句将“ 删除”创建的表。这可以毫无疑问地确定,因此可以自动生成回滚语句。
另一方面,无法确定“drop table”命令的回滚语句。无法确定表的最后状态,因此无法自动生成回滚语句。这些类型的迁移语句需要手动回滚指令。
3.编写一个简单的回滚声明
让我们编写一个简单的变更集,它将在执行时创建一个表,并向变更集添加一个回滚语句:
<changeSet id="testRollback" author="baeldung">
<createTable tableName="baeldung_turorial">
<column name="id" type="int"/>
<column name="heading" type="varchar(36)"/>
<column name="author" type="varchar(36)"/>
</createTable>
<rollback>
<dropTable tableName="baeldung_test"/>
</rollback>
</changeSet>
以上示例属于上述第一类。如果我们不添加一个语句,它将自动创建一个回滚语句。但是我们可以通过创建回滚语句来覆盖默认行为。
我们可以使用以下命令运行迁移:
mvn liquibase:update
执行后,我们可以使用以下命令回滚操作:
mvn liquibase:rollback
这将执行变更集的回滚段,并应还原在更新阶段完成的任务。但是,如果我们单独发出此命令,则构建将失败。
原因是 - 我们没有指定回滚的限制; 通过回滚到初始阶段,数据库将完全消失。因此,在满足条件时,必须定义以下三个约束之一以限制回滚操作:
- rollbackTag
- rollbackCount
- rollbackDate
3.1。回滚到标签
我们可以将数据库的特定状态定义为标记。因此,我们可以参考该状态。回滚到标签名称“1.0”看起来像:
mvn liquibase:rollback -Dliquibase.rollbackTag=1.0
这将执行标记“1.0”之后执行的所有更改集的回滚语句。
3.2。按计数回滚
在这里,我们定义了需要回滚的变更集数量。如果我们将其定义为1,则将回滚最后一个变更集执行:
mvn liquibase:rollback -Dliquibase.rollbackCount=1
3.3。回滚至今
我们可以将回滚目标设置为日期,因此,在该日之后执行的任何变更集都将回滚:
mvn liquibase:rollback "-Dliquibase.rollbackDate=Jun 03, 2017"
日期格式必须是ISO数据格式或者应该与执行平台的DateFormat.getDateInstance()的值匹配。
4.回滚更改集选项
让我们探讨变更集中回滚语句的可能用法。
4.1。多语句回滚
单个回滚标记可以包含多个要执行的指令:
<changeSet id="multiStatementRollback" author="baeldung">
<createTable tableName="baeldung_tutorial2">
<column name="id" type="int"/>
<column name="heading" type="varchar(36)"/>
</createTable>
<createTable tableName="baeldung_tutorial3">
<column name="id" type="int"/>
<column name="heading" type="varchar(36)"/>
</createTable>
<rollback>
<dropTable tableName="baeldung_tutorial2"/>
<dropTable tableName="baeldung_tutorial3"/>
</rollback>
</changeSet>
这里我们在同一个rollback标记中删除两个表。我们也可以将任务分成多个语句。
4.2。多个回滚标签
在变更集中,我们可以有多个回滚标记。它们按变更集中的外观顺序执行:
<changeSet id="multipleRollbackTags" author="baeldung">
<createTable tableName="baeldung_tutorial4">
<column name="id" type="int"/>
<column name="heading" type="varchar(36)"/>
</createTable>
<createTable tableName="baeldung_tutorial5">
<column name="id" type="int"/>
<column name="heading" type="varchar(36)"/>
</createTable>
<rollback>
<dropTable tableName="baeldung_tutorial4"/>
</rollback>
<rollback>
<dropTable tableName="baeldung_tutorial5"/>
</rollback>
</changeSet>
4.3。请参阅另一个变更集以进行回滚
如果我们要更改数据库的某些细节,我们可以引用另一个更改集,可能是原始更改集。这将减少代码重复并可以正确还原已完成的更改:
<changeSet id="referChangeSetForRollback" author="baeldung">
<dropTable tableName="baeldung_tutorial2"/>
<dropTable tableName="baeldung_tutorial3"/>
<rollback changeSetId="multiStatementRollback" changeSetAuthor="baeldung"/>
</changeSet>
4.4。空回滚标签
默认情况下,如果我们没有提供,Liquibase会尝试生成回滚脚本。如果我们需要破坏此功能,我们可以使用空的回滚标记,以便不回复回滚操作:
<changeSet id="emptyRollback" author="baeldung">
<createTable tableName="baeldung_tutorial">
<column name="id" type="int"/>
<column name="heading" type="varchar(36)"/>
<column name="author" type="varchar(36)"/>
</createTable>
<rollback/>
</changeSet>
5.回滚命令选项
除了将数据库回滚到先前的状态之外,Liquibase还可以以多种不同的方式使用。这些是,生成回滚SQL,创建未来的回滚脚本,最后,我们可以一步测试迁移和回滚。
5.1。生成回滚脚本
与回滚相同,我们有三个选项可用于生成回滚SQL。那些是:
- rollbackSQL
- 用于将数据库回滚到上述标记的脚本 - rollbackToDateSQL <date / time> - 一个SQL脚本,用于将数据库回滚到上述日期/时间的状态
- rollbackCountSQL
- 一个SQL脚本,用于将数据库回滚到之前步骤数所述的状态 让我们看看其中一个实例:
mvn liquibase:rollbackCountSQL 2
5.2。生成未来回滚脚本
此命令生成所需的回滚SQL命令,以使数据库从状态(当前有资格运行的更改集完成)进入当前状态。如果需要为我们即将执行的更改提供回滚脚本,这将非常有用:
如果需要为我们即将执行的更改提供回滚脚本,这将非常有用:
mvn liquibase:futureRollbackSQL
5.3。运行更新测试回滚
此命令执行数据库更新,然后回滚更改集以使数据库进入当前状态。在执行完成后,未来的回滚和更新测试回滚都不会改变当前数据库。但更新测试回滚执行实际迁移,然后将其回滚。
这可用于测试更新更改的执行,而无需永久更改数据库:
mvn liquibase:updateTestingRollback