liquibase
背景
- 數據庫變更管理有兩種方式,狀態和遷移方法;
- 第一種,基於狀態(或聲明性),在其中定義數據庫的所需狀態。
- 可以將目標環境和定義的所需狀態進行比較的工具用於生成允許目標環境與聲明的狀態匹配的遷移腳本。
- 第二種,基於遷移(或命令式)的方法,其中描述了用於更改數據庫狀態的特定遷移。
- 使用一種能夠顯式跟蹤和排序單個遷移並部署尚未部署到目標環境的遷移的工具,以使目標數據庫得到正確遷移。
- 從根本上來說,Liquibase 是基於遷移的解決方案,其中的diff功能僅用於協助新項目的啓動和健全性檢查,以確保數據庫遷移已正確應用。
定義
- 用於數據庫重構和遷移的開源工具;
- 用於跟蹤、管理和應用數據庫的變化;
- 通過日誌文件的形式記錄數據庫的變更,執行日誌文件中的修改,將數據庫更新或回滾到一致的狀態;
- 它將所有數據庫的變化(包括結構和數據)都保存在XML文件中,便於版本控制;
- 始終提供一種與數據庫無關的方式來交付快速、安全、可重複的數據庫部署。
工作原理
- 核心是一種簡單的機制來跟蹤、版本化和部署更改:
- 使用變更日誌(變更分類賬)以特定順序顯式列出數據庫變更。
- 使用一個跟蹤表,該表駐留在每個數據庫上,並且跟蹤已在變更日誌中部署了哪些變更集。
- 藉助 分類賬和跟蹤表,Liquibase能夠:
- 跟蹤和版本化數據庫更改–用戶確切地知道哪些更改已部署到數據庫以及哪些更改尚未部署。
- 部署更改–具體來說,通過將分類帳中的內容與跟蹤表中的內容進行比較,Liquibase能夠僅部署以前尚未部署到數據庫的更改。
- 如果Liquibase所作用的數據庫上沒有跟蹤表,則Liquibase將創建一個跟蹤表。
- Liquibase具有高級功能,例如上下文,標籤和前提條件,可精確控制何時以及在何處部署changeSet。
特性
- 跟蹤所有提議的數據庫更改,包括需要部署的特定順序,提議/編寫更改的人,並記錄更改的目錄(作爲註釋)。
- 明確回答是否已將數據庫更改部署到數據庫。有效地,Liquibase能夠"版本化"每個數據庫。
- 確定性地將更改部署到數據庫,包括將數據庫升級到特定的版本。
- 防止用戶修改已經部署到數據庫的更改,並要求他們故意重做已部署的更改或前滾。
大白話特點
- 幾乎支持所有主流的數據庫,如Mysql、Oracle、PostgreSql 和 Db2等;
- 支持多開發者的協作維護;
- 其日誌文件支持多種格式,比如Sql、xml、yaml和json;
- 支持多種運行方式,比如命令行、Maven和Gradle等。
常用命令
- 創建表
<changeSet id="init-schema" author="[email protected]" > <comment>init schema</comment> <createTable tableName="user" remarks="用戶表"> <column name="id" type="bigint" autoIncrement="${autoIncrement}" remarks="主鍵"> <constraints primaryKey="true" nullable="false"/> </column> <column name="name" type="varchar(255)" remarks="名稱"> <constraints nullable="false"/> </column> <column name="password" type="varchar(255)" remarks="密碼"> <constraints nullable="false"/> </column> </createTable> <modifySql dbms="mysql"> <append value="ENGINE=INNODB DEFAULT CHARSET utf8mb4 COLLATE utf8mb4_general_ci"/> </modifySql> </changeSet>
- 創建索引
<createIndex tableName="ven_vendor_info" indexName="idx_vendor_id"> <column name="vendor_id" /> </createIndex>
- 新增列
<addColumn tableName="users"> <column name="name" type="varchar(255)" remarks="名稱"> <constraints nullable="false"/> </column> </addColumn>
- 刪除列
<dropColumn tableName="atl_relation_vendor_company" columnName="is_deleted"/>
- 修改數據類型
<modifyDataType tableName="atl_vendor_info" columnName="import_code" newDataType="varchar(50)" />
- 重命名列
<renameColumn tableName="atl_vendor_type" oldColumnName="is_deleted" newColumnName="deleted"/>
集成SpringBoot
-
引入依賴
<dependencies> <dependency> <groupId>org.liquibase</groupId> <artifactId>liquibase-core</artifactId> </dependency> </dependencies>
-
yml文件中配置
spring: datasource: url: jdbc:mysql://127.0.0.1:3306/snow?characterEncoding=utf8&useSSL=false username: root password: 123456 driverClassName: com.mysql.jdbc.Driver type: com.alibaba.druid.pool.DruidDataSource liquibase: enabled: true change-log: "classpath:liquibase/change_log/index.xml" contexts: dev
-
變更集,即對數據庫的操作
<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.4.xsd"> <property name="autoIncrement" value="true" dbms="mysql"/> <changeSet id="init-schema" author="[email protected]" > <comment>init schema</comment> <createTable tableName="users" remarks="用戶表"> <column name="id" type="bigint" autoIncrement="${autoIncrement}" remarks="主鍵"> <constraints primaryKey="true" nullable="false"/> </column> <column name="name" type="varchar(255)" remarks="名稱"> <constraints nullable="false"/> </column> <column name="password" type="varchar(255)" remarks="密碼"> <constraints nullable="false"/> </column> </createTable> <modifySql dbms="mysql"> <append value="ENGINE=INNODB DEFAULT CHARSET utf8mb4 COLLATE utf8mb4_general_ci"/> </modifySql> </changeSet> <changeSet author="diff-generated" id="1185214997195-7"> <createIndex indexName="PK_EMP" tableName="EMP"> <column name="EMPNO"/> </createIndex> </changeSet> </databaseChangeLog>
-
index.xml,封裝一個共用的入口,通過include 引入變更集
<?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.1.xsd"> <include file="classpath:liquibase/change_log/2019-10-29-init-schema.xml" relativeToChangelogFile="false"/> </databaseChangeLog>
-
注入Bean,放入啓動類中,或者新建配置文件,添加@Configuration。
@Bean public SpringLiquibase springLiquibase(DataSource dataSource) { SpringLiquibase springLiquibase = new SpringLiquibase(); springLiquibase.setDataSource(dataSource); springLiquibase.setChangeLog("classpath:/liquibase/index.xml"); return springLiquibase; }