liquibase介绍,liquibase这一篇就够了
核心概念
首先它是用于管理数据库版本的,用于跟踪、管理和应用数据库变化,所以就会有这些概念:版本号,管理的数据,差异比较,版本回滚
它的版本号由开发人员来维护,使用 author + id
它会在你的目标数据库生成一张表 DATABASECHANGELOG 来管理版本
管理的数据最小单元为 changeSet ,通过日志文件的形式记录数据库的变更,然后执行日志文件中的修改,将数据库更新或回滚到一致的状态。所以变更日志文件一般不可更改,liquibase也自带校验其是否被变更的操作。
安装
安装本体包很简单,官网直接下载,配置system PATH
liquibase是需要java环境来运行的,支持多种数据库,每种数据库需要下载对应的Driver
jar包
使用步骤(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比较功能,比较两个库的差异然后生成补丁包
缺点
- 这种数据变动自动执行,网上通常认为其不适合于生产环境的,仅能开发测试,特指回滚功能
- sql类型不支持生成自动回滚,而其他类型需要学习成本(学习标签的使用)
- 回滚是基于changelog文件,就像goinception基于binlog。但是基于changelog的回滚功能支持度明显有限,很多语句无法生成,而对应的基于binlog的goinception,可以从binlog生成更多类型的回滚语句。
附带一个较好的使用案例
https://segmentfault.com/a/1190000021208813?utm_source=tag-newest
liquibase文档: liquibase文档
更多推荐
所有评论(0)