zoukankan      html  css  js  c++  java
  • Liquibase 使用(全)

    聊一个数据库脚本的版本工具 Liquibase,官网在这里 ,初次看到,挺神奇的,数据库脚本也可以有版本管理,同类型的工具还有 flyway 。

    开发过程经常会有表结构和变更,让运维来维护的话,通常会有很大的沟通成本,有时在开发方案有问题的时候,提测失败整个项目需要回滚,代码回滚起来是很容易的,通常有备份,但数据库的话就要人工来逐行分析并写出回滚语句,Liquibase 这时候就有用了。

    Liquibase 适用场景感觉不多,所以可能有人没听过它的名头; 首先这种自动执行的家伙肯定是不适合于生产环境的,然后在数据量大的时候是不可能用数据库自带的 alter 语句的,一般都是手动创建另一张表,然后用 sql 语句将数据批量复制过去,再者使用容器化也比它好,个人觉得它一般用于开发和测试环境,比较厉害的一个功能是可以比较两个库的差异然后生成补丁包,上线时可以这么玩。

    这篇文章 说得不错,我是在这篇基本上写的

    核心概念

    首先它是用于管理数据库版本的,所以就会有这些概念:版本号,管理的数据,差异比较,版本回滚

    它的版本号由开发人员来维护,使用 author + id

    管理的数据最小单元为 changeSet ,这个 changeSet 看官网说是可以用 xml,yaml,json,sql 来编写

    提交数据,比较差异,版本回滚 可以使用命令行 或者 maven ,ant 等构建工具来完成

    从命令行开始

    看网上说的都是集成自 springboot ,但这种数据库脚本一般公司都是运维在维护,使用命令行是最方便的方式,所以我先说下使用命令行,官网示例

    为先为了不每次都要写一大堆参数,可以在 liquibase 根目录加一个 liquibase.properties,用于配置数据库 jar 包,url ,用户名,密码等参数,配置详情

    命令格式: liquibase [options] [command] [command parameters]

    比较开发库和测试库的差异,并生成升级包

    如果要升级哪个,则哪个要做为源,则配置中的 url 不是 referenceUrl,使用如下命令创建升级包

    liquibase --changeLogFile="changeLogFiledevtest.postgresql.sql" diffChangeLog
    

    changeLogFile 是有命名规则的,命名必须为 *.dbType.format ,如上所示

    为测试库打一个标签

    liquibase tag v1.0
    

    使用差异升级源库

    liquibase --changeLogFile="sqls/changeLogFiledevtest.postgresql.sql" update
    

    升级有问题需要回滚

    liquibase 有几种回滚策略,一种是根据标签回滚,回滚次数,和根据日期回滚;有 9 个与之对应的命令

    回滚要求对应的 changeLogFile 有回滚标签 ,这个在后面文件格式说

    # 按照 changeSet 次数回滚
    liquibase  --changeLogFile="sqls/changeLogFiledevtest.postgresql.sql" rollbackCount 1
    # 按照标签回滚
    liquibase  --changeLogFile="sqls/changeLogFiledevtest.postgresql.sql" rollback v1.0
    

    生成数据库脚本(新环境)

    liquibase --changeLogFile="sqls/create_table.mysql.sql"  generateChangeLog
    

    原理

    它会在你的目标数据库生成一张表 DATABASECHANGELOG 来管理版本 ,另一个 lock 的是防止多人同时操作数据库加的锁。

    文件格式

    其实各种文件格式使用生成数据库脚本就可以看到格式了,照着写就行

    sql 文件格式

    --liquibase formatted sql
    
    --changeset <author>:<version> 
    sqls
    
    --rollback rollback sqls 
    
    --comment: 注释都有特殊含义了,所以注释要这样加
    
    

    详情见官网 sql 文件格式

    XML 文件格式

    xml 比 sql 更加可控,它可以加一个预判断条件,来判断这个后面的 changeSet 要不要执行,但相应的就必须照它的语法来写语句了,没 sql 方便了,还好提供了 xsd

    <preConditions>
        <runningAs username="liquibase"/>
    </preConditions>
    
    <!-- 版本 1 的修改-->
    <changeSet id="1" author="sanri">
        <addColumn tableName="person">
            <column name="username" type="varchar(8)"/>
        </addColumn>
    </changeSet>
    

    见官网 XML 文件格式

    json 和 yaml 就不说了,更加不好控

    使用构建工具

    前面说了,我们也可以使用 maven 来执行这些操作,引入 maven 的一个插件就行

    <plugin>
        <groupId>org.liquibase</groupId>
        <artifactId>liquibase-maven-plugin</artifactId>
        <version>3.6.3</version>
        <configuration>
                        <!--指定执行主文件 -->
    <!--                    <changeLogFile>${basedir}/src/main/resources/liquibase/master_changelog.xml</changeLogFile>-->
    <!--                    <diffChangeLogFile>${basedir}/src/main/resources/liquibase/changelog/${maven.build.timestamp}_changelog.xml</diffChangeLogFile>-->
    <!--                    <outputChangeLogFile>${basedir}/src/main/resources/liquibase/changelog/changelog_original.xml</outputChangeLogFile>-->
    
                       <propertyFile>src/main/resources/liquibase/liquibase.properties</propertyFile>
    
                        <dropFirst>false</dropFirst>
                        <verbose>true</verbose>
                        <logging>debug</logging>
                        <!-- 是否需要弹出确认框 -->
                        <promptOnNonLocalDatabase>false</promptOnNonLocalDatabase>
                        <!--输出文件的编码 -->
                        <outputFileEncoding>UTF-8</outputFileEncoding>
                        <!--执行的时候是否显示详细的参数信息 -->
                        <verbose>true</verbose>
                        <!--是否每次都重新加载properties -->
                        <propertyFileWillOverride>true</propertyFileWillOverride>
                        <rollbackTag>${project.version}</rollbackTag>
                        <tag>${project.version}</tag>
                    </configuration>
    </plugin>
    

    相应的命令做成了目标(goal),使用 -Dkey=value 来指定参数,如

    # 执行更新 sql 
    mvn liquibase:update -DchangeLogFile="file"
    # 打标签,这个版本号在插件中配置成项目版本了
    mvn liquibase:tag 
    # 将当前库导出表结构
    mvn liquibase:generateChangeLog 
    

    集成进 springboot ,在项目启动的时候执行版本管理

    网上都说的这种,感觉这种最不靠谱,自动执行的,万一 sql 有个错误,虽然他是把每个 changeSet 做为一个事务,需要不断的重启项目, jenkins 每次构建很慢的,如果让运维来手动重启又不现实。

    集成进 springboot

    一点小推广

    创作不易,希望可以支持下我的开源软件,及我的小工具,欢迎来 gitee 点星,fork ,提 bug 。

    Excel 通用导入导出,支持 Excel 公式
    博客地址:https://blog.csdn.net/sanri1993/article/details/100601578
    gitee:https://gitee.com/sanri/sanri-excel-poi

    使用模板代码 ,从数据库生成代码 ,及一些项目中经常可以用到的小工具
    博客地址:https://blog.csdn.net/sanri1993/article/details/98664034
    gitee:https://gitee.com/sanri/sanri-tools-maven

  • 相关阅读:
    HTTP协议
    浏览器兼容性问题
    面试笔试重点总结:操作系统、计算机网络、设计模式
    笔试、面试重点总结:算法基础、数据结构
    笔试、面试重点总结:WIN32、MFC与Linux
    《Java程序员面试笔试宝典》终于在万众期待中出版啦~
    《Java程序员面试笔试宝典》之Static关键字有哪些作用
    《Java程序员面试笔试宝典》之字符串创建与存储的机制是什么
    《Java程序员面试笔试宝典》之为什么需要public static void main(String[] args)这个方法
    《Java程序员面试笔试宝典》之Java变量命名有哪些规则
  • 原文地址:https://www.cnblogs.com/sanri1993/p/12125280.html
Copyright © 2011-2022 走看看