使用Liquibase和Spring Boot進行資料庫遷移的一站式指南 - reflectoring
Liquibase有助於自動化資料庫遷移,而Spring Boot使使用Liquibase更加容易。該指南提供了有關如何在Spring Boot應用程式中使用Liquibase的詳細資訊以及一些最佳實踐。
本文隨附GitHub上的工作程式碼示例。
資料庫遷移工具可幫助我們跟蹤,版本控制和自動執行資料庫架構更改。它們幫助我們在不同環境中擁有一致的架構。
Liquibase簡介
Liquibase不僅使用簡單的舊SQL指令碼,而且還使用不同的抽象的,與資料庫無關的格式(包括XML,YAML和JSON)來促進資料庫遷移。當我們使用非SQL格式進行資料庫遷移時,Liquibase會為我們生成特定於資料庫的SQL。它照顧不同資料庫的資料型別和SQL語法的變化。它支援大多數流行的關聯式資料庫。
Liquibase允許通過Liquibase擴充套件對其當前支援的資料庫進行增強。這些擴充套件也可用於新增對其他資料庫的支援。
讓我們看一下Liquibase的核心概念:
- ChangeSet:changeSet是一組需要應用於資料庫的更改。Liquibase在ChangeSet級別跟蹤更改的執行。
- Change變更:變更描述了需要應用於資料庫的單個變更。Liquibase開箱即用提供了幾種更改型別,例如“建立表”或“刪除列”,它們都是對SQL的抽象。
- Changelog變更日誌:具有需要應用的資料庫變更集列表的檔案稱為變更日誌。這些變更日誌檔案可以採用SQL,YAML,XML或JSON格式。
- Preconditions前提條件: 前提條件用於控制變更日誌或變更集的執行。它們用於定義需要在其下執行changeSets或change日誌的資料庫狀態。
- Context上下文:changeSet可以用上下文表示式標記。在給定特定上下文的情況下,Liquibase將評估此表示式以確定是否應在執行時執行changeSet。您可以將上下文表示式與環境變數進行比較。
- Labels標籤:標籤目標類似上下文。區別在於changeSet用標籤(而不是表示式)列表標記,並且在執行時,我們可以傳遞標籤表示式來選擇與表示式匹配的changeSet。
- Changelog引數:Liquibase允許我們在changelog中使用佔位符,它在執行時會動態替換。
Liquibase會建立兩個表,databasechangelog 並databasechangeloglock在第一次在資料庫中執行時建立。它使用該databasechangelog表來跟蹤databasechangeloglockchangeSets 的執行狀態,並防止Liquibase併發執行。有關更多詳細資訊,請參考文件。
Spring Boot的Liquibase
預設情況下,當我們將Liquibase依賴項新增到構建檔案中時,Spring Boot會自動配置Liquibase 。
Spring Boot使用主資料庫DataSource執行Liquibase.如果我們需要使用其他名稱DataSource,可以將該bean標記為@LiquibaseDataSource。
另外,我們可以設定spring.liquibase.[url,user,password]屬性,以便spring自己建立一個資料來源,並使用它來自動配置Liquibase。
預設情況下,Spring Boot在應用程式啟動時自動執行Liquibase資料庫遷移。
在類路徑中名為db/migration的資料夾中查詢主變更日誌檔案db.changelog-master.yaml。如果要使用其他Liquibase變更日誌格式或使用不同的檔案命名約定,則可以將spring.liquibase.change-log應用程式屬性配置為指向其他主變更日誌檔案。
例如,要用db/migration/my-master-change-log.json作主變更日誌檔案,我們在中設定以下屬性application.yml:
spring: liquibase: changeLog: "classpath:db/migration/my-master-change-log.json" |
主變更日誌可以包括其他變更日誌,以便我們可以按邏輯步驟將變更拆分。
執行我們的第一個資料庫遷移
設定完所有內容後,讓我們建立我們的第一個資料庫遷移。在本示例中,我們將建立資料庫表user_details。
讓我們建立一個具有名稱的檔案db.changelog-master.yaml並將其放置在中src/main/resources/db/changelog:
databaseChangeLog: - include: file: db/changelog/db.changelog-yaml-example.yaml |
主檔案只是一個包含集合的集合,這些集合指向具有實際更改的更改日誌。
接下來,我們使用第一個實際的變更集建立變更日誌,並將其放入檔案中src/main/resources/db/changelog-yaml-example.yaml:
databaseChangeLog: - changeSet: id: create-table-user author: liquibase-demo-service preConditions: - onFail: MARK_RAN not: tableExists: tableName: user_details changes: - createTable: columns: - column: autoIncrement: true constraints: nullable: false primaryKey: true primaryKeyName: user_pkey name: id type: BIGINT - column: constraints: nullable: false name: username type: VARCHAR(250) - column: constraints: nullable: false name: first_name type: VARCHAR(250) - column: name: last_name type: VARCHAR(250) tableName: user_details |
我們使用了changeType createTable,它抽象了表的建立。Liquibase將基於我們的應用程式使用的資料庫將上述changeSet轉換為適當的SQL。
在執行此更改之前,preCondition檢查user_details表是否不存在。如果該表已經存在,則Liquibase會將changeSet標記為已成功執行而不實際執行。
現在,當我們執行Spring Boot應用程式時,Liquibase執行changeSet,該表將建立user_details表,user_pkey作為主鍵。
使用變更日誌引數
當我們要為不同的環境使用不同的值替換佔位符時,Changelog引數非常有用。我們可以使用application屬性設定這些引數spring.liquibase.parameters,該屬性採用鍵/值對的對映:
spring: profiles: docker liquibase: parameters: textColumnType: TEXT contexts: local --- spring: profiles: h2 liquibase: parameters: textColumnType: VARCHAR(250) contexts: local |
我們設定Liquibase引數textColumnType來VARCHAR(250)時春啟動的啟動h2配置檔案,並TEXT當它在啟動docker配置檔案(假定泊塢窗型材啟動一個“真正”的資料庫)。
現在,我們可以在變更日誌中使用此引數:
databaseChangeLog: - changeSet: ... changes: - createTable: columns: ... - column: constraints: nullable: false name: username type: ${textColumnType} |
現在,當Spring Boot應用程式在docker配置檔案中執行時,它將TEXT用作列型別,並在h2配置檔案中使用VARCHAR(250)。
使用Liquibase上下文
上下文可用於控制應執行哪些changeSet。讓我們用它在test和local環境中新增測試資料:
<databaseChangeLog> <changeSet author="liquibase-docs" id="loadUpdateData-example" context="test or local"> <loadUpdateData encoding="UTF-8" file="db/data/users.csv" onlyUpdate="false" primaryKey="id" quotchar="'" separator="," tableName="user_details"> </loadUpdateData> </changeSet> </databaseChangeLog> |
我們正在使用該表示式test or local,它可以在這些上下文中執行,但不適用於生產環境。
現在,我們需要使用屬性將上下文傳遞給Liquibase spring.liquibase.contexts:
--- spring: profiles: docker liquibase: parameters: textColumnType: TEXT contexts: test |
在Spring Boot中配置Liquibase
下面是Spring Boot提供的用於配置Liquibase行為的所有屬性的列表。
- spring.liquibase.changeLog 主變更日誌配置路徑。預設為classpath:/db/changelog/db.changelog-master.yaml,
- spring.liquibase.contexts 要使用的執行時上下文的逗號分隔列表。
- spring.liquibase.defaultSchema 用於託管資料庫物件和Liquibase控制表的模式。
- spring.liquibase.liquibaseSchema Liquibase控制表的架構。
- spring.liquibase.liquibaseTablespace 用於Liquibase物件的表空間。
- spring.liquibase.databaseChangeLogTable 指定用於跟蹤更改歷史記錄的其他表。預設值為DATABASECHANGELOG。
- spring.liquibase.databaseChangeLogLockTable 指定用於跟蹤併發Liquibase使用情況的其他表。預設值為DATABASECHANGELOGLOCK。
- spring.liquibase.dropFirst 指示是否在執行遷移之前刪除資料庫架構。請勿在生產中使用!預設值為false。
- spring.liquibase.user 登入使用者名稱以連線到資料庫。
- spring.liquibase.password 登入密碼以連線到資料庫。
- spring.liquibase.url 要遷移的資料庫的JDBC URL。如果未設定,則使用主要配置的資料來源。
- spring.liquibase.labels 執行liquibase時要使用的標籤表示式。
- spring.liquibase.parameters 引數對映將傳遞給Liquibase。
- spring.liquibase.rollbackFile 執行更新時將回滾SQL寫入的檔案。
- spring.liquibase.testRollbackOnUpdate 在執行更新之前是否應該測試回滾。預設值為false。
在Spring Boot中啟用Liquibase的日誌記錄
INFO為Liquibase 啟用級別日誌記錄將有助於檢視Liquibase在應用程式啟動期間執行的changeSet。它還有助於識別應用程式尚未啟動,因為它在啟動過程中正在等待獲取變更日誌鎖。
在其中新增以下應用程式屬性application.yml以啟用INFO日誌:
logging: level: "liquibase" : info |
使用Liquibase的最佳實踐
- 組織變更日誌:建立一個主變更日誌檔案,該檔案沒有實際的變更集,但包含其他變更日誌(僅YAML,JSON和XML支援(包括include),而SQL不包含)。這樣做使我們可以將changeSets組織在不同的changelog檔案中。每次我們向需要資料庫更改的應用程式新增新功能時,我們都可以建立一個新的變更日誌檔案,將其新增到版本控制中,並將其包含在主變更日誌中。
- 每個ChangeSet只能進行一次更改:每個changeSet只能進行一次更改,因為在應用changeSet失敗的情況下,這可以使回滾更加容易。
- 不要修改ChangeSet:一旦更改集執行完畢,就不要再對其進行修改。相反,如果需要修改現有changeSet所應用的更改,則新增新的changeSet。Liquibase跟蹤已執行的changeSet的校驗和。如果修改了已經執行的changeSet,預設情況下,Liquibase將無法再次執行該changeSet,並且不會繼續執行其他changeSet。
- ChangeSet Id:Liquibase允許我們為changeSets使用描述性名稱。最好使用唯一的描述性名稱作為changeSetId,而不要使用序列號。它們使多個開發人員可以新增不同的changeSet,而不必擔心他們需要為changeSetId選擇的下一個序列號。
- 參考資料管理:使用Liquibase來填充應用程式所需的參考資料和程式碼表。這樣做可以一起部署所需的應用程式和配置資料。Liquibase提供了changeType loadUpdateData支援此功能。
- 使用前提條件:具有changeSets的前提條件。他們確保Liquibase在應用更改之前檢查資料庫狀態。
- 測試遷移:在將其應用於實際的非生產或生產環境之前,請確保始終測試本地編寫的遷移。始終使用Liquibase在非生產或生產環境中執行資料庫遷移,而不是手動執行資料庫更改。
在Spring Boot應用程式啟動期間自動執行Liquibase,可以輕鬆地將應用程式程式碼更改和資料庫更改一起提供。但是,在向具有大量資料的現有資料庫表新增索引的情況下,應用程式可能需要更長的時間才能啟動。一種選擇是預釋出資料庫遷移(在需要它的程式碼之前釋放資料庫更改)並非同步執行它們。
其他執行Liquibase的方法
Liquibase除了支援Spring Boot整合外,還支援一系列其他選項來執行資料庫遷移:
- 通過Maven外掛
- 通過Gradle外掛
- 通過命令列
- 通過JEE CDI整合
- 通過Servlet偵聽器
Liquibase有一個Java API,我們可以在任何基於Java的應用程式中使用它來執行資料庫遷移。
相關文章
- Spring Boot中兩個資料庫遷移工具Liquibase和Flyway的比較 - 4lexSpring Boot資料庫UI
- SpringBoot資料庫管理 - 用Liquibase對資料庫管理和遷移?Spring Boot資料庫UI
- 使用Spring Boot和Swagger進行API優先開發 - reflectoring.ioSpring BootSwaggerAPI
- 如何使用Spring Boot和Flyway建立不同資料庫的多租戶應用? - reflectoring.ioSpring Boot資料庫
- Spring Boot整合Spring Data JPA進行資料庫操作Spring Boot資料庫
- 資料庫上雲實踐:使用Ora2pg進行資料庫遷移資料庫
- Flowable 6.6.0 BPMN使用者指南 - (5)Spring Boot - 5.11 使用Liquibase 5.12 進一步閱讀Spring BootUI
- Laravel migration (資料庫遷移) 的使用Laravel資料庫
- Spring Boot 簡單整合 LiquibaseSpring BootUI
- Spring Boot通過@ConfigurationProperties訪問靜態資料 - reflectoringSpring Boot
- 使用dbeaver 用csv 檔案進行資料遷移
- 使用 Spring Boot 和 @SpringBootTest 進行測試Spring Boot
- 使用Mobilenet和Keras進行遷移學習!Keras遷移學習
- 資料庫遷移資料庫
- EF Core 小技巧:遷移已經應用到資料庫,如何進行遷移回退操作?資料庫
- Spring Boot中使用PostgreSQL資料庫Spring BootSQL資料庫
- Spring、Spring Boot和TestNG測試指南 – 整合測試中用Docker建立資料庫Spring BootDocker資料庫
- 使用Spring Data JPA進行資料庫操作Spring資料庫
- Sentry 開發者貢獻指南 - 資料庫遷移資料庫
- 使用Spring Boot的Configuration和ArchUnit實現元件模組化和清晰邊界 - reflectoringSpring Boot元件
- Oracle資料庫中資料行遷移與行連結Oracle資料庫
- 1.5 使用nvicat和kettle進行全量遷移
- 使用資料泵(expdp、impdp)遷移資料庫流程資料庫
- ThinkPHP5.1 中的資料庫遷移和資料填充PHP資料庫
- redis資料庫遷移Redis資料庫
- 資料庫遷移 :理解資料庫
- laravel資料庫遷移Laravel資料庫
- Laravel 使用 sql 語句 和 sql 檔案 來建立執行資料庫遷移LaravelSQL資料庫
- Laravel資料庫遷移和填充(支援中文)Laravel資料庫
- 使用vplex的mirror功能對儲存層LUN進行資料的遷移
- Alibaba 資料庫遷移開源工具 Datax 安裝和使用資料庫開源工具
- Spring Boot應用程式事件教程 - reflectoringSpring Boot事件
- 使用impdp,expdp資料泵進入海量資料遷移
- 資料庫調優和資料遷移是如何影響資料庫的RY資料庫
- Spring Boot中使用時序資料庫InfluxDBSpring Boot資料庫UX
- 【Redis 技術探索】「資料遷移實戰」手把手教你如何實現線上 + 離線模式進行遷移 Redis 資料實戰指南(scan模式遷移)Redis模式
- linux mysql資料庫遷移LinuxMySql資料庫
- django資料庫遷移-15Django資料庫