為什么要使用liquibase?
- 團隊協作與版本管理
?- 當多人(或多個小組)并行開發、對同一數據庫結構進行變更時,如果僅靠手寫 SQL 腳本,很 容易產生沖突或漏掉某些變更。
?-?Liquibase 將所有 DDL/DML 操作以“changeset”形式納入源碼管理(Git、SVN),保證每條變更都有明確記錄、能回溯,比單純的 SQL 文件更具可控性。
- 環境一致性與自動化部署
?- 在開發、測試、預生產、生產等多套環境中,手動執行腳本不僅繁瑣,還容易漏執行或順序錯亂。
?- Liquibase 可在應用啟動或 CI/CD 流水線中自動檢測并執行“待跑”變更集,確保各環境數據庫始終與代碼版本保持一致。
-?回滾與容災能力
?-?手動腳本一旦執行錯誤,回滾往往要手寫“撤銷腳本”,既費時又容易出錯。
? -?在 Liquibase 中,每個 changeset 都可以定義 rollback 邏輯,部署失敗時能夠精準回退到前一個健康狀態。
-?防止數據庫“漂移”
?-?長期演進過程中,數據庫實際結構可能與預期文檔或代碼不同步,導致線上問題排查困難。
?-?Liquibase 通過維護 DATABASECHANGELOG
表,自動對比歷史記錄與變更腳本,及時發現并修復結構漂移。
-?合規審計需求
?-?某些行業(金融、醫療、政府)對數據庫變更有嚴格審計和備案要求,需要完整的操作記錄和執行人信息。
?-?Liquibase 的 DATABASECHANGELOG
表會記錄每條變更的執行時間、執行人和執行狀態,天然滿足審計需求。
等等....這里我們先介紹springboot整合liquibase的配置,數據庫版本控制和自動執行和回滾
springboot整合liquibase
- 將所有建表、修改表結構、插入初始數據等操作都以“changeset”(變更集)的形式記錄在 XML、YAML、JSON 或 SQL 文件中,存儲在項目源碼里,類似于 Git 管理代碼的方式。
?-?每次啟動應用時,Liquibase 會自動對比當前數據庫已執行的變更集與源碼中的變更集,確保數據庫結構與代碼版本一致。
-?在 Spring Boot 啟動階段,Liquibase 自動掃描并執行未應用的變更集,無需手動在數據庫端運行腳本。支持為每條變更集定義回滾(rollback)邏輯,遇到部署錯誤或回滾需求時,可以精準撤銷指定版本的數據庫變更。
-?Liquibase 提供 diff
、diffChangeLog
命令,可比對兩個數據庫之間的結構差異,自動生成變更集腳本,便于團隊協作和歷史回顧。還能導出數據庫的當前快照或變更歷史,生成 HTML、JSON 等格式的數據庫文檔
-?Liquibase 在數據庫中維護一個 DATABASECHANGELOG
表,記錄每個變更集的執行時間、執行人等信息,方便事后審計和問題定位。
-?支持 Oracle、MySQL、PostgreSQL、SQL Server、DB2、H2、SQLite 等主流關系型數據庫,跨數據庫平臺保持統一的變更管理方式。
1、導入liquibase所需的依賴并引入Liquibase的插件:
<!-- Liquibase 核心引擎 --><dependency><groupId>org.liquibase</groupId><artifactId>liquibase-core</artifactId><version>4.33.0</version></dependency><!--Liquibase所需的依賴--><dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId><version>3.13.0</version></dependency>
<plugin><groupId>org.liquibase</groupId><artifactId>liquibase-maven-plugin</artifactId><version>4.33.0</version><configuration><!-- 指定 changelog 主入口文件,用于 update 等命令 -->
<changeLogFile>src/main/resources/liquibase/changelog/master.xml</changeLogFile><!-- 指定 generateChangeLog 的輸出文件 -->
<outputChangeLogFile>src/main/resources/liquibase/changelog/generated/init-schema.xml</outputChangeLogFile><!-- 添加數據庫連接信息 --><url>jdbc:mysql://yourhost:3306/yourDbSchema?useUnicode=true&characterEncoding=utf-8&autoReconnect=true&useSSL=false&serverTimezone=Asia/Shanghai</url><username>yoursqlname</username><password>yoursqlpassword</password><driver>com.mysql.cj.jdbc.Driver</driver></configuration><executions><execution><phase>process-resources</phase><goals><goal>generateChangeLog</goal></goals></execution></executions><!-- 添加依賴 --><dependencies><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.33</version></dependency></dependencies></plugin>
注意插件的版本要和依賴的一致
?2、yml文件配置基本信息:
spring:liquibase:change-log: classpath:liquibase/changelog/master.xml # 指定XML路徑enabled: true # true-當 Spring Boot 啟動時,自動啟用 Liquibase,并執行你在 changelog.xml 中定義的數據庫變更 false-禁用 Liquibase,不會自動執行任何 changelog 邏輯
3、按照插件的<changeLogFile>標簽和<outputChanegLogFile>標簽構建文件架構:
4、在master.xml文件上配置信息:
<databaseChangeLogxmlns="http://www.liquibase.org/xml/ns/dbchangelog"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangeloghttp://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.1.xsd"><include file="generated/init-schema.xml" relativeToChangelogFile="true"/>
</databaseChangeLog>
5、調用liquibase插件執行 liquibase:generateChangeLog根據數據庫生成init-schema.xml:
執行成功后就會生成該文件并生成sql對應的xml代碼:
?我們可以將它交給git管理,團隊成員在拉取我們git分支時就可以通過運行項目自動讀取xml文件同步我們的數據庫
6、日常應用:
假設開發人員需要在數據庫表contracts上新增一個字段status,直接在init-schema.xml上進行維護。
使用<changeSet>標簽添加在表的<changeSet>下面:
<changeSet author="Layux" id="202507251618"><addColumn tableName="contracts"><column name="status" remarks="狀態" type="TINYINT"><constraints nullable="false"/></column></addColumn></changeSet>
id可以使用時間的形式,方便后期維護
然后執行mvn liquibase:update,這樣在datebasechangelog表上就會記錄這次的操作
同時 數據庫表contracts上也會新增這個status字段
7、回滾(回滾后datebasechangelog表的記錄數據會消失,操作表中的變更會退回)
rollbackCount(按數量回滾):
命令:
mvn liquibase:rollback -Dliquibase.rollbackCount=1
建議補充rollback塊:
<changeSet author="Layux" id="202507251618"><addColumn tableName="contracts"><column name="status" remarks="狀態" type="TINYINT"><constraints nullable="false"/></column></addColumn><rollback><dropColumn tableName="contracts" columnName="status"/></rollback>
</changeSet>
rollbackTag(按標簽):
<changeSet id="1753429943969-1" author="32452">...<tagDatabase tag="before_status_added"/>
</changeSet>
建議添加?<rollback>
塊
命令:
mvn liquibase:rollback -Dliquibase.rollbackTag=before_status_added
rollbackToDate(按時間)
命令:
mvn liquibase:rollback -Dliquibase.rollbackDate=2025-07-25T16:20:00
該時間點應早于 status
字段添加時間
?建議添加?<rollback>
塊
生成 SQL 回滾語句(手動執行)
命令:
mvn liquibase:rollbackSQL -Dliquibase.rollbackCount=1
建議添加?<rollback>
塊
8、變更,sql表分文件(可選)
在大型項目中,為例方便維護,常常一表一文件
1、我們可以使用在入口的master.xml文件統一引入:
eg:
<databaseChangeLog ...><include file="tables/user.xml" relativeToChangelogFile="true"/><include file="tables/dept.xml" relativeToChangelogFile="true"/><include file="tables/contract.xml" relativeToChangelogFile="true"/>
</databaseChangeLog>
?2、使用Python腳本自動拆分:
讀取
init-schema.xml
每當遇到一個
<changeSet>
,分析其中的表名(如<createTable tableName="users">
)將每個
<changeSet>
寫入獨立的users.xml
、contracts.xml
等文件自動生成
changelog-master.xml
并用<include>
引入
?分文件維護:在變更表的過程中,我們常常將每個變更都分xml文件存儲,表名可以用日期或者變更備注
eg:
src/main/resources/liquibase/
├── changelog/
│ ? ├── master.xml ? ? ? ? ? ? ? ? ?# 主 changelog 文件
│ ? ├── 2024/
│ ? │ ? ├── 20240701-add-user-table.xml
│ ? │ ? ├── 20240710-add-status-column.xml
│ ? │ ? └── ...
│ ? └── 2025/
│ ? ? ? ├── 20250725-update-contracts-status.xml
│ ? ? ? └── ...
1、配置主changelog文件(master.xml)
<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLogxmlns="http://www.liquibase.org/xml/ns/dbchangelog"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangeloghttp://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.8.xsd"><!-- 引用子文件 --><include file="liquibase/changelog/2024/20240701-add-user-table.xml"/><include file="liquibase/changelog/2024/20240710-add-status-column.xml"/><include file="liquibase/changelog/2025/20250725-update-contracts-status.xml"/></databaseChangeLog>
2、新建子 changelog 文件(每個文件一個 changeSet)
<?xml version="1.0" encoding="utf-8"?>
<databaseChangeLogxmlns="http://www.liquibase.org/xml/ns/dbchangelog"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangeloghttp://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.8.xsd"><changeSet id="20250725-1" author="layux"><preConditions onFail="MARK_RAN"><not><columnExists tableName="contracts" columnName="status"/></not></preConditions><addColumn tableName="contracts"><column name="status" type="TINYINT" defaultValueNumeric="0" remarks="狀態"/></addColumn></changeSet></databaseChangeLog>