核心概念

首先它是用于管理数据库版本的,用于跟踪、管理和应用数据库变化,所以就会有这些概念:版本号,管理的数据,差异比较,版本回滚
它的版本号由开发人员来维护,使用 author + id
它会在你的目标数据库生成一张表 DATABASECHANGELOG 来管理版本
管理的数据最小单元为 changeSet ,通过日志文件的形式记录数据库的变更,然后执行日志文件中的修改,将数据库更新或回滚到一致的状态。所以变更日志文件一般不可更改,liquibase也自带校验其是否被变更的操作。

安装

安装本体包很简单,官网直接下载,配置system PATH
liquibase是需要java环境来运行的,支持多种数据库,每种数据库需要下载对应的Driverjar包
在这里插入图片描述

使用步骤(sql)

在这里插入图片描述
1.准备好sql
2.创建changelog文件,并在文件中写changesets
3.使用changelog应用到目标数据库

运行输出例子:
Running Changeset: example-changelog.sql::1::your.name
Running Changeset: example-changelog.sql::2::your.name
Running Changeset: example-changelog.sql::3::other.dev
Liquibase command ‘update’ was executed successfully.

如上所示,Changeset是一个一个执行的

changelog的使用

liquibase支持4种格式的changelog的使用,分别是SQL,XML,JSON,YAML
其中使用liquibase时,学习成本最低的是sql,有更多可控性的是xml(可以添加changeset的执行条件)。

这里简单介绍一下

SQL格式

--liquibase formatted sql
----  your.name:1的含义<author>:<version>
----  labels:标签
--changeset your.name:1 labels:example-label context:example-context
--comment: example comment
create table person (
    id int primary key auto_increment not null,
    name varchar(50) not null,
    address1 varchar(50),
    address2 varchar(50),
    city varchar(30)
)
--rollback DROP TABLE person;

--changeset your.name:2 labels:example-label context:example-context
--comment: example comment
create table company (
    id int primary key auto_increment not null,
    name varchar(50) not null,
    address1 varchar(50),
    address2 varchar(50),
    city varchar(30)
)
-- -- 回滚语句要这样写:
--rollback DROP TABLE company;

--changeset other.dev:3 labels:example-label context:example-context
--comment: example comment
alter table person add column country varchar(2)
--rollback ALTER TABLE person DROP COLUMN country;

XML格式

<?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"
        xmlns:pro="http://www.liquibase.org/xml/ns/pro"
        xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.6.xsd
    http://www.liquibase.org/xml/ns/pro http://www.liquibase.org/xml/ns/pro/liquibase-pro-4.6.xsd ">
	
      <changeSet id="1" author="your.name" labels="example-label" context="example-context">
          <comment>example-comment</comment>
        <createTable tableName="person">
            <column name="id" type="int" autoIncrement="true">
                <constraints primaryKey="true" nullable="false"/>
            </column>
            <column name="name" type="varchar(50)">
                <constraints nullable="false"/>
            </column>
            <column name="address1" type="varchar(50)"/>
            <column name="address2" type="varchar(50)"/>
            <column name="city" type="varchar(30)"/>
        </createTable>
    </changeSet>

    <changeSet id="2" author="your.name" labels="example-label" context="example-context">
        <comment>example-comment</comment>
        <createTable tableName="company">
            <column name="id" type="int" autoIncrement="true">
                <constraints primaryKey="true" nullable="false"/>
            </column>
            <column name="name" type="varchar(50)">
                <constraints nullable="false"/>
            </column>
            <column name="address1" type="varchar(50)"/>
            <column name="address2" type="varchar(50)"/>
            <column name="city" type="varchar(30)"/>
        </createTable>
    </changeSet>

    <changeSet id="3" author="other.dev" labels="example-label" context="example-context">
        <comment>example-comment</comment>
        <addColumn tableName="person">
            <column name="country" type="varchar(2)"/>
        </addColumn>
    </changeSet>
</databaseChangeLog>

github里的例子:
例子

如何确定链接的目标数据库

方式一
通过配置文件:

# Enter the path for your changelog file.
changeLogFile=example-changelog.sql

#### 目标数据库的url  ####
liquibase.command.url=jdbc:h2:tcp://localhost:9090/mem:dev

# 目标数据库的用户
liquibase.command.username: dbuser

# 目标数据库的密码
liquibase.command.password: letmein

#### Enter the Source Database 'referenceUrl' information ####
## The source database is the baseline or reference against which your target database is compared for diff/diffchangelog commands.

# Enter URL for the source database
liquibase.command.referenceUrl: jdbc:h2:tcp://localhost:9090/mem:integration

# Enter the username for your source database
liquibase.command.referenceUsername: dbuser

# Enter the password for your source database
liquibase.command.referencePassword: letmein

例如阿里云RDS的url是
jdbc:mysql://mydb.123456789012.us-east-1.rds.amazonaws.com:3306/myTestDB?autoReconnect=true&useSSL=false
方式二
在命令行种指定用户名密码
在这里插入图片描述

重要命令介绍

update

  • update
    部署已在更改日志文件中但尚未部署到数据库中的任何更改。
    当你运行更新命令时,Liquibase 顺序读取变更记录文件中的变更,然后将 id、 author 和 path to filename 等唯一标识符与 databaschangelog 表中存储的值进行比较。
    • 如果不存在唯一标识符,则 Liquibase 将对数据库应用变更集。
    • 如果存在则对changeset进行MD5Sum比较,不一样则说明有人改变了此changset,会报错(也有配置能忽略此错误强行应用执行: runAlways)
  • Update-count
    命令按顺序更新数据库上指定数量的变更集
  • update-to-tag
    Update-to-tag 命令主要用于按顺序应用更改,从更改日志文件顶部的更改集开始,直到到达指定的标记。比如指定tag为version1:
    在这里插入图片描述

rollback

回滚的逻辑
找回滚标签
如果没有回滚标签定义,试图推断出所需要的回滚语句
如果没有足够的信息来回滚,则无法回滚

回滚注意事项
1.回滚功能并不能生成所有语句的回滚
许多更改类型(如创建表、重命名列和添加列)都可以自动创建回滚语句。如果您的更改日志只包含属于此类别的语句,则将自动生成回滚命令。
其他更改类型(如删除表和插入数据)没有相应的可自动生成的回滚命令。在这些情况下,以及希望覆盖默认生成的回滚命令的情况下,可以通过变更集标记指定回滚命令。如果不想撤消回滚模式中的更改,可以使用空的回滚tag。
如“drop table”没有 对应的回滚命令可以自动生成,liquibase并不知道如果创建这张表

2.不支持格式化的sql语句回滚,需要自己写回滚语句
在写changset时自己指定无法生成的回滚语句:
链接: 自动回滚的支持

使用案例

-- changeset liquibaseuser:1
create table Details1 ( id int primary key, name varchar(255) );
-- rollback drop table Details1;

xml指定多句回滚:

<changeSet  author="liquibase"  id="30">
  <createTable tableName="table30">
    <column name="id" type="int"/>
    <column name="heading" type="varchar(36)"/>
    <column name="author" type="varchar(36)"/>
  </createTable>
<rollback>
drop table table30
</rollback>
</changeSet>

<changeSet id="multiRollbackTest" author="rs">
  <createTable tableName="multiRollback1">
    <column name="id" type="int"/>
  </createTable>
  <createTable tableName="multiRollback2">
    <column name="id" type="int"/>
  </createTable>
  <createTable tableName="multiRollback3">
    <column name="id" type="int"/>
  </createTable>
<rollback>
drop table multiRollback1;
drop table multiRollback2;
</rollback>
<rollback>drop table multiRollback3</rollback>
</changeSet>
  • rollback --tag
    根据指定的tag执行回滚
    在这里插入图片描述
  • rollback-count
    当您希望按顺序回滚更改时,可以使用 rollback-count 命令,从最近的更改开始,向后回滚,直到达到指定的值。
    下面的图像显示了三个变更集: 变更集 a、变更集 b 和变更集 c。运行命令 rollback-count 3,回滚最后三个变更集。
    在这里插入图片描述
  • rollback-one-update
    回滚一次更新(使用 rollback-one-update 命令会带来可能意想不到的风险)
    可根据–deploymentId *回滚指定的deploymentId
    在这里插入图片描述

其他亮眼功能

在update、rollback之前都可以执行一下内置的对应校验功能(虽然基本只能liquibase PRO用户使用)
对应校验功能会校验changeset有没有发生变更,来避免不可预料的错误

diff命令可以比较2个数据库


Diff Results:
Reference Database: MYSCHEMA2 @ jdbc:oracle:thin:@localhost:1521:ORCL (Default Schema: MYSCHEMA2)
Comparison Database: MYSCHEMA @ jdbc:oracle:thin:@localhost:1521:ORCL (Default Schema: MYSCHEMA)
Compared Schemas: MYSCHEMA2 -> MYSCHEMA
Product Name: EQUAL
Product Version: EQUAL
Missing Catalog(s): NONE
Unexpected Catalog(s): NONE
Changed Catalog(s): NONE
Missing Check Constraint(s): NONE
Unexpected Check Constraint(s): NONE
Changed Check Constraint(s): NONE
Missing Column(s): NONE
Unexpected Column(s):
	MYSCHEMA.DEPARTMENT.ACTIVE
	MYSCHEMA.SERVICETECH.ACTIVE
	MYSCHEMA.SERVICETECH2.ACTIVE
	MYSCHEMA.SERVICETECH3.ACTIVE
	MYSCHEMA.VIEW1.ACTIVE
	MYSCHEMA.DEPARTMENT.ID
	MYSCHEMA.SERVICETECH.ID
	MYSCHEMA.SERVICETECH2.ID
	MYSCHEMA.SERVICETECH3.ID
	MYSCHEMA.VIEW1.ID
	MYSCHEMA.DEPARTMENT.NAME
	MYSCHEMA.SERVICETECH.NAME
	MYSCHEMA.SERVICETECH2.NAME
	MYSCHEMA.SERVICETECH3.NAME
	MYSCHEMA.VIEW1.NAME
Changed Column(s): NONE
Missing Database Package(s): NONE
Unexpected Database Package(s): NONE
Changed Database Package(s): NONE
Missing Database Package Body(s): NONE
Unexpected Database Package Body(s): NONE
Changed Database Package Body(s): NONE
Missing Foreign Key(s): NONE
Unexpected Foreign Key(s): NONE
Changed Foreign Key(s): NONE
Missing Function(s): NONE
Unexpected Function(s): NONE
Changed Function(s): NONE
Missing Index(s): NONE
Unexpected Index(s):
	PK_DEPARTMENT UNIQUE  ON MYSCHEMA.DEPARTMENT(ID)
	PK_SERVICETECH UNIQUE  ON MYSCHEMA.SERVICETECH(ID)
	PK_SERVICETECH2 UNIQUE  ON MYSCHEMA.SERVICETECH2(ID)
	PK_SERVICETECH3 UNIQUE  ON MYSCHEMA.SERVICETECH3(ID)
Changed Index(s): NONE
Missing Java Class(s): NONE
Unexpected Java Class(s): NONE
Changed Java Class(s): NONE
Missing Java Source(s): NONE
Unexpected Java Source(s): NONE
Changed Java Source(s): NONE
Missing Primary Key(s): NONE
Unexpected Primary Key(s):
	PK_DEPARTMENT on MYSCHEMA.DEPARTMENT(ID)
	PK_SERVICETECH on MYSCHEMA.SERVICETECH(ID)
	PK_SERVICETECH2 on MYSCHEMA.SERVICETECH2(ID)
	PK_SERVICETECH3 on MYSCHEMA.SERVICETECH3(ID)
Changed Primary Key(s): NONE
Missing Sequence(s): NONE
Unexpected Sequence(s): NONE
Changed Sequence(s): NONE
Missing Stored Procedure(s): NONE
Unexpected Stored Procedure(s): NONE
Changed Stored Procedure(s): NONE
Missing Synonym(s): NONE
Unexpected Synonym(s): NONE
Changed Synonym(s): NONE
Missing Table(s): NONE
Unexpected Table(s):
	DEPARTMENT
	SERVICETECH
	SERVICETECH2
	SERVICETECH3
Changed Table(s): NONE
Missing Trigger(s): NONE
Unexpected Trigger(s): NONE
Changed Trigger(s): NONE
Missing Unique Constraint(s): NONE
Unexpected Unique Constraint(s): NONE
Changed Unique Constraint(s): NONE
Missing View(s): NONE
Unexpected View(s):
	VIEW1
Changed View(s): NONE
Liquibase command 'diff' was executed successfully.

优点:
1.多种数据库支持
2.数据库变更版本管理化
3.支持多种类型的changelog文件
4.基于changeset的update、rollback精细化操作
5.支持diff比较功能,比较两个库的差异然后生成补丁包

缺点

  1. 这种数据变动自动执行,网上通常认为其不适合于生产环境的,仅能开发测试,特指回滚功能
  2. sql类型不支持生成自动回滚,而其他类型需要学习成本(学习标签的使用)
  3. 回滚是基于changelog文件,就像goinception基于binlog。但是基于changelog的回滚功能支持度明显有限,很多语句无法生成,而对应的基于binlog的goinception,可以从binlog生成更多类型的回滚语句。

附带一个较好的使用案例

https://segmentfault.com/a/1190000021208813?utm_source=tag-newest

liquibase文档: liquibase文档

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐