Liquibase作为一款开源的数据库架构变更管理工具,可以帮助开发者方便跟踪、管理数据库变化的修订。其支持MySQL、PostgreSQL、Oracle等众多数据库
集成Spring
Spring boot内置了对Liquibase的支持,只需要在项目中引入Liquibase依赖并进行配置即可
<!--Liquibase-->
<dependency>
<groupId>org.liquibase</groupId>
<artifactId>liquibase-core</artifactId>
<version>3.6.3</version>
</dependency>
对于配置而言,Liquibase默认会使用Spring配置项的数据库连接。如果期望不使用该默认配置,也可以显式单独配置
# 数据库配置
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/db1?useSSL=false
spring.datasource.username=root
spring.datasource.password=123456
# 使能 Liquibase
spring.liquibase.enabled=true
# 指定 Liquibase 变更记录的位置
spring.liquibase.change-log=classpath:/db/changelog/master.xml
在上面的配置项spring.liquibase.change-log中我们指定了Liquibase 变更记录的位置。事实上,通常这只是一个master配置文件,如下所示。其中通过include标签来包含、汇聚所有的changlog文件
<?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.9.xsd">
<!-- master.xml文件的作用就是汇集所有changlog文件 -->
<!-- relativeToChangelogFile 为 true 时表示使用的是相对路径 而不是classpath-->
<include file="changelog-1.0.xml" relativeToChangelogFile="true"/>
</databaseChangeLog>
目录结构如下所示
详解ChangeLog
一个典型地changlog文件如下所示,其记录了我们对数据库的变更、修订内容。这里我们使用XML进行介绍,其实Liquibase支持SQL、XML、JSON、YAML等多种形式
<?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.9.xsd">
<changeSet id="create_density_range" author="Aaron" runOnChange="true">
<!-- 执行该SQL的先决条件: 该表不存在 -->
<preConditions onError="MARK_RAN" onFail="MARK_RAN">
<not>
<tableExists tableName="density_range"/>
</not>
</preConditions>
<createTable remarks="密度区间" tableName="density_range">
<column name="id" type="INTEGER" remarks="主键id" autoIncrement="true" startWith="1" incrementBy="1">
<constraints primaryKey="true" nullable="false"/>
</column>
<column name="low_start" remarks="低密度区间: 下限" type="INTEGER"/>
<column name="low_end" remarks="低密度区间: 上限" type="INTEGER"/>
<column name="medium_start" remarks="中密度区间: 下限" type="INTEGER"/>
<column name="medium_end" remarks="中密度区间: 上限" type="INTEGER"/>
<column name="high_start" remarks="高密度区间: 下限" type="INTEGER"/>
<column name="high_end" remarks="高密度区间: 上限" type="INTEGER"/>
</createTable>
</changeSet>
<changeSet id="create_geohash_6" author="Aaron" runOnChange="true">
<preConditions onError="MARK_RAN" onFail="MARK_RAN">
<not>
<tableExists tableName="geohash_6"/>
</not>
</preConditions>
<createTable remarks="GeoHash6信息" tableName="geohash_6">
<column name="id" type="INTEGER" remarks="主键id" autoIncrement="true" startWith="1" incrementBy="1">
<constraints primaryKey="true" nullable="false"/>
</column>
<column name="geohash" remarks="GeoHash6数据" type="VARCHAR(255)"/>
<column name="center_lng" remarks="中心点经度" type="VARCHAR(255)"/>
<column name="center_lat" remarks="中心点纬度" type="VARCHAR(255)"/>
<column name="max_lng" remarks="最大经度" type="VARCHAR(255)"/>
<column name="max_lat" remarks="最大纬度" type="VARCHAR(255)"/>
<column name="min_lng" remarks="最小经度" type="VARCHAR(255)"/>
<column name="min_lat" remarks="最小纬度" type="VARCHAR(255)"/>
<column name="is_hz_edge" remarks="是否为边界" type="BOOLEAN"/>
</createTable>
</changeSet>
<changeSet id="add tag" author="Aaron">
<!-- tag 为版本号 -->
<tagDatabase tag="1.0"/>
</changeSet>
</databaseChangeLog>
-
「changeSet标签」:出于便于阅读的角度考虑,每个changeSet每次只包含对一张表的修订操作。同时,对于已执行过changeSet一般情况下不应做任何修改 -
「runOnChange属性」:用于控制每次运行changeSet时,如果本次changeSet发生修改是否重新执行。其默认值为false,当本次changeSet发生修改不会执行变更,而是会发出错误以提醒发生了意外修改。其原理是通过比对changeSet的MD5校验和、存储在DATABASECHANGELOG表中的MD5SUM进行 判定的。典型地对于存储过程场景而言,该属性一般设置为true。这样每次对历史changeSet进行修改后,都需要Liquibase重新执行该changeSet以保证修改生效 -
「preConditions标签」:控制数据库变更的先决条件。如果先决条件满足要求,则会执行该标签后相应的数据库变更;如果先决条件在执行过程抛出异常,则行为由「onError属性」控制;如果先决条件不满足要求,则行为由「onFail属性」控制; -
「onFail、onError属性」:preConditions标签的onFail、onError属性可用的取值有: -
「CONTINUE」:跳过该changeSet、会在下次更新时再次尝试。继续执行changeLog -
「HALT」:停止执行整个changeLog。这也是默认值 -
「MARK_RAN」:跳过该changeSet同时将其标记为已执行。继续执行changeLog -
「WARN」:发出警告并继续执行changeSet、changeLog -
「tagDatabase」:对本次版本的数据库修订打标签
至此当我们启动SpringBoot项目后,即可发现数据库不仅包含了我们期望的业务表,还新增了两张Liquibase相关的表——DATABASECHANGELOG、DATABASECHANGELOGLOCK
而对于DATABASECHANGELOGLOCK锁表而言,如果某记录的LOCKED字段为1,则表示该锁被占有了。故在Liquibase锁无法正常释放时,可能会导致无法创建表,这时可通过手动置零来释放锁
生成ChangeLog
liquibase-maven-plugin可以帮助我们直接地从数据库中创建、生成相应的ChangeLog文件,配置如下
<build>
<plugins>
<plugin>
<groupId>org.liquibase</groupId>
<artifactId>liquibase-maven-plugin</artifactId>
<version>3.6.3</version>
<configuration>
<!--生成Changelog的输出目录-->
<outputChangeLogFile>${basedir}/src/main/resources/db/generate/changeLog.xml</outputChangeLogFile>
<!--DB连接信息-->
<driver>com.mysql.jdbc.Driver</driver>
<url>jdbc:mysql://localhost:3306/db1?useSSL=false</url>
<username>root</username>
<password>123456</password>
<dropFirst>false</dropFirst>
<verbose>true</verbose>
<logging>debug</logging>
<promptOnNonLocalDatabase>false</promptOnNonLocalDatabase>
<outputFileEncoding>UTF-8</outputFileEncoding>
<propertyFileWillOverride>true</propertyFileWillOverride>
</configuration>
</plugin>
</plugins>
</build>
操作、效果如下所示
原文始发于微信公众号(青灯抽丝):浅谈Liquibase
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/156501.html