这片文章用于梳理项目中用到的Liquibase。
Liquibase是一种开源的数据库迁移工具(Database migration tool),官网上对它的描述是“source control of database”,即数据库的版本管理工具。常用的数据库迁移工具还有flyway,会在后续文章中总结。Liquibase支持各种主流数据库,如Mysql,PostgreSQL,DB2,Oracle,SQL server,H2,Hsql等。
如何在Spring Boot项目中使用Liquibase?
Step1. 在项目中引入Liquibase依赖。如下图build.gradle中声明liquibase-core依赖。
Step 2. 把changelog放在/db/changelog/db.changelog-master.yaml。/db/changelog/db.changelog-master.yaml是Spring Boot查找changelog的默认路径,Spring Boot启动时,会自动运行liquibase进行数据库迁移。同时也可以通过配置属性liquibase.change-log=<path/changelogFile>来自定义change log路径。
Liquibase的核心就是用changeLog文件来记录跟踪数据库更新。Liquibase支持的changeLog格式包括:XML,JSON,YAML和SQL。这里我们以XML为例,如下图所示,changeLog用‘databaseChangeLog’标签表示,可以包含多个changeSet.
Step 3. 定义changeSet。ID和Auther必填,其中ID可以是数字也可以是表义的字符串;其他信息包括Context,PreConditions,Sql和Rollback语句。上图中的change set用于创建Factory数据表。
Liquibase运行时会顺序读取change log中定义的change set,并基于change set的ID,author和change log文件路径查看该change set是否已经存在于“databasechangelog”数据表,存在代表已经执行过,则跳过该change set(除非runAlways置为true)。change set执行完成后,会基于ID,author和change log文件路径生成MD5值存储到“databasechangelog”数据表,用于防止change set在被执行后发生修改。如果change set在执行后被修改,那么Liquibase运行时会报错并停止数据库更新,以避免出现数据库状态与change log期待状态的不一致。
Liquibase最佳实践
1. 使用major release来组织change log。如db.changelog-1.0.xml;db.changelog-1.1.xml;db.changelog-2.0.xml。
2. 使用Master change log引用各个major release change log,引用顺序即为release顺序。如下图所示。
3. 每个change set仅包含单个数据库修改。因为liquibase把一个change set作为一个事务;而某些数据库支持statement自动提交,因此通常做法是一个change set仅包含一个数据库修改。
Liquibase的其他功能
1. 支持生成数据库更新文档,如下图所示,包括当前数据表结构,历次change log等信息。
2. 类似VCS的diff功能,Liquibase提供diff命令查看数据库的修改,尽管开发过程中每次修改都有change log,但是diff命令可以帮助我们比如在上线之前查看并确认数据库的修改。
3. 提供SQL Output模式。项目中有时并不希望Liquibase自动完成数据库更新,比如我们需要DBA审批等,那么Liquibase的SQL Output模式可以仅生成用于更新和回滚的SQL语句,而不会进行真正的更新。