boot-admin整合Liquibase實現(xiàn)數(shù)據(jù)庫版本管理

Liquibase 和 Flyway 是兩款成熟的、優(yōu)秀的、開源/商業(yè)版的數(shù)據(jù)庫版本管理工具,鑒于 Flyway 的社區(qū)版本對 Oracle 數(shù)據(jù)庫支持存在限制,所以 boot-admin 選擇整合 Liquibase 提供數(shù)據(jù)庫版本管理能力支持。
Liquibase 開源版使用 Apache 2.0 協(xié)議。

Liquibase的適用情形?

  • 在你的項目進行版本升級的時候,大概率情況下數(shù)據(jù)庫也需要同步升級,Liquibase 會自動掃描數(shù)據(jù)庫遷移文件(changeSet),將遷移文件的版本號與歷史記錄表(changelog )中的版本號進行對比,略過已執(zhí)行的的遷移文件,順序執(zhí)行未執(zhí)行的新版本遷移文件,最終實現(xiàn)數(shù)據(jù)庫與代碼版本相匹配;
  • 當多人協(xié)作開發(fā)項目的時候,系統(tǒng)源代碼可使用 git 保持同步,那么數(shù)據(jù)庫的同步就可交由 liquibase 來保證;
  • 使用 liquibase 可以方便地比較兩個數(shù)據(jù)庫的差異;
  • 使用 liquibase 還支持數(shù)據(jù)庫版本回滾。

Liquibase的優(yōu)點有哪些?

  1. 配置文件支持SQL、XML、JSON 或者 YAML;
  2. 可兼容14種主流數(shù)據(jù)庫如 oracle,mysql 等,支持平滑遷移;
  3. 版本控制按序執(zhí)行;
  4. 可以用上下文控制sql在何時何地如何執(zhí)行;
  5. 具備在應(yīng)用中具有if / then邏輯的能力;
  6. 支持 schema 的變更;
  7. 根據(jù)配置文件自動生成sql語句用于預(yù)覽;
  8. 可重復(fù)執(zhí)行遷移;
  9. 可插件拓展;
  10. 可回滾;
  11. 支持schema方式的多租戶(multi-tenant);
  12. 能夠在多種數(shù)據(jù)庫類型上具有相同的更改描述;
  13. 生成的數(shù)據(jù)庫歷史記錄文檔;
  14. 能夠輕松指定更復(fù)雜的多語句更改。

整合要點

boot-admin 是一款采用前后端分離模式、基于 SpringCloud 微服務(wù)架構(gòu)的SaaS后臺管理框架。系統(tǒng)內(nèi)置基礎(chǔ)管理、權(quán)限管理、運行管理、定義管理、代碼生成器和辦公管理6個功能模塊,集成分布式事務(wù) Seata、工作流引擎 Flowable、業(yè)務(wù)規(guī)則引擎 Drools、后臺作業(yè)調(diào)度框架 Quartz 等,技術(shù)棧包括 Mybatis-plus、Redis、Nacos、Seata、Flowable、Drools、Quartz、SpringCloud、Springboot Admin Gateway、Liquibase、jwt、Openfeign、I18n等。

項目源碼倉庫github
項目源碼倉庫gitee

引入Maven依賴

<dependency>
    <groupId>org.liquibase</groupId>
    <artifactId>liquibase-core</artifactId>
</dependency>

添加配置

spring:
  liquibase:
    enabled: true
    change-log: classpath:liquibase/master.xml

創(chuàng)建master.xml

在 resources 下創(chuàng)建文件夾 liquibase ,創(chuàng)建文件 master.xml

<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">

    <includeAll path="liquibase/changelogs/" relativeToChangelogFile="false"/>

</databaseChangeLog>

在 liquibase 文件夾下創(chuàng)建 changelogs 和 sql 兩個文件夾,如下圖所示:


dir.png

編寫數(shù)據(jù)庫變更單元 changeSet

在 resources\liquibase\changelogs 下創(chuàng)建 changeSet 文件,推薦每月一個 xml 文件,文件名格式:【changelog-年度+月份.xml】,如:changelog-202304.xml
常用操作舉例:

創(chuàng)建表

    <changeSet author="admin (generated)" id="00001-9">
        <createTable remarks="行政區(qū)劃表" tableName="TB_ADM_DIV">
            <column name="GUID" remarks="主鍵" type="NVARCHAR2(38)">
                <constraints nullable="false" primaryKey="true" primaryKeyName="PK_TB_ADM_DIV"/>
            </column>
            <column name="ADM_DIV_CODE" remarks="行政區(qū)劃代碼" type="NVARCHAR2(12)">
                <constraints nullable="false"/>
            </column>
            <column name="ADM_DIV_NAME" remarks="行政區(qū)劃名稱" type="NVARCHAR2(100)">
                <constraints nullable="false"/>
            </column>
            <column name="CREATE_BY" remarks="記錄創(chuàng)建者" type="NVARCHAR2(100)">
                <constraints nullable="false"/>
            </column>
            <column name="CREATE_TIME" remarks="記錄創(chuàng)建時間" type="${type.datetime}">
                <constraints nullable="false"/>
            </column>
            <column name="MODIFY_BY" remarks="記錄最后修改者" type="NVARCHAR2(100)">
                <constraints nullable="false"/>
            </column>
            <column name="MODIFY_TIME" remarks="記錄最后修改時間" type="${type.datetime}">
                <constraints nullable="false"/>
            </column>
            <column defaultValueComputed="${now}" name="DATESTAMP" remarks="時間戳" type="${type.datetime}">
                <constraints nullable="false"/>
            </column>
            <column name="ENABLED" remarks="啟用狀態(tài);ENABLED" type="NVARCHAR2(1)">
                <constraints nullable="false"/>
            </column>
            <column name="DELETED" remarks="刪除狀態(tài);DELETED" type="NVARCHAR2(1)">
                <constraints nullable="false"/>
            </column>
            <column name="VERSION" remarks="樂觀鎖" type="${type.int}">
                <constraints nullable="false"/>
            </column>
            <column name="REMARKS" remarks="備注" type="NVARCHAR2(900)"/>
            <column name="TENANT_ID_" remarks="租戶ID" type="NVARCHAR2(38)">
                <constraints nullable="false"/>
            </column>
            <column name="PARENT_GUID" remarks="父級GUID" type="NVARCHAR2(38)">
                <constraints nullable="false"/>
            </column>
            <column name="LEAF" remarks="是否末級;YESNO" type="NVARCHAR2(1)">
                <constraints nullable="false"/>
            </column>
            <column name="SORT" remarks="順序號" type="${type.int}">
                <constraints nullable="false"/>
            </column>
        </createTable>
    </changeSet>

添加表字段

    <changeSet author="admin" id="00002-1">
        <addColumn tableName="TB_ADM_DIV">
            <column name="EXT" remarks="擴展" type="VARCHAR(64)"/>
        </addColumn>
     </changeSet>

刪除表字段

    <changeSet author="admin" id="00002-2">
        <dropColumn tableName="TB_ADM_DIV" columnName="EXT"/>
    </changeSet>

修改表字段說明

    <changeSet author="admin" id="00002-3">
        <setColumnRemarks tableName="TB_ADM_DIV" columnName="EXT" remarks="擴展字段"/>
    </changeSet>

修改表字段類型

    <changeSet author="admin" id="00002-4">
        <modifyDataType tableName="TB_ADM_DIV" columnName="EXT" newDataType="VARCHAR2(2000)"/>
    </changeSet>

創(chuàng)建視圖

    <changeSet author="admin (generated)" id="00001-1" dbms="oracle">
        <createView fullDefinition="true" remarks="表和視圖" viewName="V_TABLES_MASTER">
            CREATE OR REPLACE FORCE VIEW V_TABLES_MASTER (TABLE_SCHEMA, TABLENAME, TABLETYPE, COMMENTS, TENANT_ID_) AS
            select SYS_CONTEXT('USERENV','CURRENT_SCHEMA') TABLE_SCHEMA,
            t.tname tableName,
            tabtype tabletype,
            f.comments comments,
            'DEMO' TENANT_ID_
            from tab t
            inner join user_tab_comments f
            on t.tname = f.table_name
            where tname != 'DATABASECHANGELOG'
            and tname != 'DATABASECHANGELOGLOCK'
            and tname != 'UNDO_LOG'
        </createView>
    </changeSet>
    <changeSet author="37514 (generated)" id="00000-2" dbms="mysql">
        <createView fullDefinition="true" remarks="表和視圖" viewName="V_TABLES_MASTER">
            CREATE OR REPLACE VIEW V_TABLES_MASTER  AS
            SELECT
            TABLE_SCHEMA,
            TABLE_NAME AS TABLENAME,
            case when table_type='BASE TABLE' then 'TABLE' ELSE table_type END AS TABLETYPE,
            TABLE_COMMENT AS COMMENTS,
            'DEMO' TENANT_ID_
            FROM
            information_schema.`TABLES`
            WHERE table_name != 'databasechangeloglock' AND TABLE_NAME != 'databasechangelog' AND TABLE_NAME != 'undo_log'
        </createView>
    </changeSet>

兼容 Oracle 和 Mysql 配置

    <property name="type.datetime" value="date" dbms="oracle"/>
    <property name="type.datetime" value="timestamp" dbms="mysql"/>
    <property name="type.int" value="NUMBER(*, 0)" dbms="oracle"/>
    <property name="type.int" value="INT" dbms="mysql"/>
    <property name="type.decimal" value="NUMBER(*, 2)" dbms="oracle"/>
    <property name="type.decimal" value="DECIMAL" dbms="mysql"/>
    <property name="now" value="SYSDATE" dbms="oracle"/>
    <property name="now" value="now()" dbms="mysql,h2"/>
    <property name="autoIncrement" value="true" dbms="mysql,h2,postgresql,oracle"/>
    <property name="amount" value="decimal(20,2)"/>
    <property name="uuid" value="sys_guid()" dbms="oracle"/>
    <property name="uuid" value="UUID()" dbms="mysql"/>

執(zhí)行 SQL 文件

    <changeSet id="20000820-003" author="Administrator" dbms="oracle">
        <sqlFile dbms="oracle" path="classpath:/liquibase/sql/seata-undo_log-oracle.sql" />
    </changeSet>
    <changeSet id="20000820-003" author="Administrator" dbms="mysql">
        <sqlFile dbms="mysql" path="classpath:/liquibase/sql/seata-undo_log-mysql.sql" />
    </changeSet>

需將對應(yīng) sql 文件放在指定文件夾中。

Liquibase changeSet常用命令清單

add

標簽 描述
addAutoIncrement 將一個已存在的列轉(zhuǎn)換為自增
addColunm 增加列
addDefaultValue 對已存在的列增加默認值
addForeignKeyConstraint 對已存在的列增加外鍵約束
addLookupTable 創(chuàng)建外鍵關(guān)聯(lián)的表
addNotNullConstraint 對已存在的列增加非空約束
addPrimaryKey 對已存在的列增加主鍵約束
ddUniqueConstraint 對已存在的列增加主鍵約束

create

標簽 描述
createIndex 創(chuàng)建索引
createProcedure 創(chuàng)建存儲過程
createSequence 創(chuàng)建序列
createTable 創(chuàng)建表
createView 創(chuàng)建視圖

drop

標簽 描述
dropAllForeignKeyConstraints 刪除全部的外鍵約束
dropColumn 刪除列
dropDefaultValue 刪除默認值設(shè)置
dropForeignKeyConstraint 刪除某一列的外鍵約束
dropNotNullConstraint 刪除非空約束
dropIndex 刪除索引
dropSequence 刪除約束
dropProcedure 刪除存儲過程
dropPrimaryKey 刪除主鍵
dropTable 刪除表
dropUniqueConstraint 刪除唯一性約束
dropView 刪除視圖

rename

標簽 描述
renameColumn 重命名列
renameSequence 重命名序列
renameTable 重命名表
renameView 重命名視圖

sql

標簽 描述
sql 原生SQL
sqlFile 引入 SQL 文件

other

標簽 描述 標簽 描述
alterSequence 修改序列 customChange 自定義change類型,需要自己實現(xiàn)liquibase.change.custom.CustomSqlChange、liquibase.change.custom.CustomTaskChange接口
delete 刪除數(shù)據(jù) empty 空操作
executeCommand 執(zhí)行系統(tǒng)命令,如 mysqldump insert 插入數(shù)據(jù)
loadData 加載 csv 文件到已存在的表中 loadUpdateData 加載 csv 文件到已存在的表中,但是會判斷是否存在,存在更新,否則新增
mergeColumns 將兩列值合并在一起,存入新列中 modifyDataType 修改列數(shù)據(jù)類型
output 記錄一條消息并繼續(xù)執(zhí)行 setColumnRemarks 列上添加備注
setTableRemarks 表上添加備注 stop 通過消息停止 Liquibase
tagDatabase 將標簽應(yīng)用于數(shù)據(jù)庫以供將來回滾 update 更新數(shù)據(jù)
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容