数据库变更管理:Liquibase or Flyway

2023-10-27

《从零打造项目》系列文章

工具

ORM框架选型

数据库变更管理

  • 数据库变更管理:Liquibase or Flyway

前言

研发过程中经常涉及到数据库变更,对表结构的修复及对数据的修改,为了保证各环境都能正确的进行变更,我们可能需要维护一个数据库升级文档来保存这些记录,有需要升级的环境按文档进行升级。

这样手工维护有几个缺点:

  1. 无法保证每个环境都按要求执行
  2. 遇到问题不一定有相对的回滚语句
  3. 无法自动化

为了解决这些问题,我们进行了一些调研,主要调研对象是 Liquibase 和 Flyway,我们希望通过数据库版本管理工具实现以下几个目标:

  1. 数据库升级
  2. 数据库回滚
  3. 版本标记

Liquibase还是Flyway

Flyway 和 Liquibase 都支持专业数据库重构和版本控制所需的所有功能,因此您将始终知道要处理的数据库模式的版本以及它是否与软件版本匹配。两种工具都集成在 Maven 或 Gradle 构建脚本中以及 Spring Boot 生态系统中,因此您可以完全自动化数据库重构。

Flyway 使用 SQL 定义数据库更改,因此您可以定制 SQL 脚本,使其与基础数据库技术(例如Oracle或PostgreSQL)良好地配合使用。另一方面,使用 Liquibase,您可以通过使用 XML,YAML 或 JSON 来定义数据库更改来引入抽象层。因此,Liquibase 更适合在具有不同基础数据库技术的不同环境中安装的软件产品中使用。

Flyway

数据库的变更可以用 SQL 或者 Java 来记录,Flyway 通过下面的步骤实现数据库变更:

  1. Flyway 先在数据库中检查自己的元数据表(默认为SCHEMA_VERSION)是否存在,如果没有,则创建一个;
  2. 检查 classpath 中所有的变更;
  3. 对比变更和自己的表,如果变更的版本低于或等于当前版本,不做任何变动;
  4. 否则,变更会按从低到高排序,并依次执行;
  5. 执行完,在 SCHEMA_VERSION 做相应的记录
Liquibase

工作方式与 Flyway 非常类似,但是 Liquibase 稍微复杂点,这点后续会单独介绍。

对比

两者的基本功能其实都差不多:

  • 都是 Java 开发的开源数据库变更管理工具
  • 支持大部分的数据库
  • 和 Maven/Gradle 无缝集成
  • 和 Spring 无缝集成
  • 非常类似的变更实现方式
  • 复杂变更如果 SQL 不能满足的话,都可以用 Java 代码实现

较大区别是 Flyway 的变更以纯 SQL 为脚本,简单直接;Liquibase 比较厚重,当然花样也比较多,包括:

  • 可指定不同的 profile
  • 具有通用的变更操作支持不同的数据库,如 createTable
  • Liquibase 开源版本支持 diff 模式,而此特性 Flyway 必须用商业版
  • Liquibase 开源版本支持回滚 rollback,而此特性 Flyway 必须用商业版,Liquibase 的付费版本据说对不同种类的回滚有更复杂的支持。
  • 两者指定变更执行顺序的方法不同,Flyway 通过固定的文件名格式来确定顺序,而 Liquibase 就是通过给定文件的顺序来执行,所以开发人员还要遵守好命名规则,例如按照日期/时间顺序命名

如果您想完全控制 SQL,Flyway 是首选工具,因为您可以使用完全定制的 SQL 甚至 Java 代码来更改数据库。多种数据源的情况下使用 Liquibase 会更加合适,不需要维护多种数据库脚本,和学习多种数据库语言,Liquibase 对于大型项目更加友好。

综上所述,我们在项目中选择 Liquibae。接下来简单来认识一下 Liquibase。

Liquibase

介绍

Liquibase 是一个用于数据库重构和迁移的开源工具,通过日志文件的形式记录数据库的变更,然后执行日志文件中的修改,将数据库更新或回滚到一致的状态。它的目标是提供一种数据库类型无关的解决方案,通过执行 schema 类型的文件来达到迁移。其优点主要有以下:

  • 支持几乎所有主流的数据库,如MySQL, PostgreSQL, Oracle, Sql Server, DB2等;
  • 支持多开发者的协作维护;
  • 日志文件支持多种格式,如XML, YAML, JSON, SQL等;
  • 支持多种运行方式,如命令行、Spring集成、Maven插件、Gradle插件等。

liquibase 官方文档地址: http://www.liquibase.org/documentation/index.html

本地安装

根据自己的操作系统下载对应的二进制包,下载地址:https://www.liquibase.org/dow…

我这里下载的是 Mac 版本的压缩包,然后在本地解压,解压包存放位置为:

/Library/liquibase-4.4.3 

sudo vi ~/.bash_profile,修改环境变量配置文件:

export PATH="/Library/liquibase-4.4.3:$PATH"

然后 source ~/.bash_profile,使配置文件生效。

最后执行下述命令,验证是否安装成功。

 % liquibase --version
####################################################
##   _     _             _ _                      ##
##  | |   (_)           (_) |                     ##
##  | |    _  __ _ _   _ _| |__   __ _ ___  ___   ##
##  | |   | |/ _` | | | | | '_ \ / _` / __|/ _ \  ##
##  | |___| | (_| | |_| | | |_) | (_| \__ \  __/  ##
##  \_____/_|\__, |\__,_|_|_.__/ \__,_|___/\___|  ##
##              | |                               ##
##              |_|                               ##
##                                                ## 
##  Get documentation at docs.liquibase.com       ##
##  Get certified courses at learn.liquibase.com  ## 
##  Free schema change activity reports at        ##
##      https://hub.liquibase.com                 ##
##                                                ##
####################################################
Starting Liquibase at 10:06:20 (version 4.4.3 #53 built at 2021-08-05 18:32+0000)
Running Java under /Library/Java/JavaVirtualMachines/jdk1.8.0_301.jdk/Contents/Home/jre (Version 1.8.0_301)

Liquibase Version: 4.4.3
Liquibase Community 4.4.3 by Datical

下载 PostgreSQL 驱动到 lib 包中,下载地址为:https://jdbc.postgresql.org/download.html

本次下载版本为:42.2.12

结合Idea使用

Liquibase问题

随着项目的发展,一个项目中的代码量会非常庞大,同时数据库表也会错综复杂。如果一个项目使用了Liquibase对数据库结构进行管理,越来越多的问题会浮现出来。

  1. ChangeSet 文件同时多人在修改,自己的 ChangeSet 被改掉,甚至被删除掉。
  2. 开发人员将 ChangeSet 添加到已经执行过的文件中,导致执行顺序出问题。
  3. 开发人员擅自添加对业务数据的修改,其它环境无法执行并报错。
  4. ChangeSet 中 SQL 包含 schema 名称,导致其它环境 schema 名称变化时,ChangeSet 报错。
  5. 开发人员不小心改动了已经执行过的 ChangeSet,在启动时会报错。
Liquibase基本规范
  1. ChangeSet id 使用[任务ID]-[日期]-[序号],如 T100-20181009-001
  2. ChangeSet 必须填写 author
  3. Liquibase 禁止对业务数据进行 sql 操作
  4. 使用<sql>时,禁止包含 schema 名称
  5. Liquibase 禁止使用存储过程
  6. 所有表,列要加 remarks 进行注释
  7. 已经执行过的 ChangeSet 严禁修改。
  8. 不要随便升级项目 liquibase 版本,特别是大版本升级。不同版本 ChangeSet MD5SUM 的算法不一样。
根据发布进行管理
  1. 每个发布新建一个文件夹,所有发布相关的 ChangeSet 文件以及数据初始化文件,均放在些文件夹中。
  2. 每个发布新建一个 master.xml。此 master.xml 中,include 本次发布需要执行的 ChangeSet 文件
  3. 根据开发小组独立 ChangeSet文件(可选)
  4. 根据功能独立 ChangeSet 文件。例如 user.xml, company.xml
resources
  |-liquibase
    |-user
    | |- master.xml
    | |- release.1.0.0
    | | |- release.xml
    | | |- user.xml -- 用户相关表ChangeSet
    | | |- user.csv -- 用户初始化数据
    | | |- company.xml -- 公司相关表ChangeSet
    | |- release.1.1.0
    | | |- release.xml
    | | |- ...
模块化管理

首先说明一下 Spring Boot 中 Liquibase 默认是如何执行以及执行结果。

  1. 在启动时,LiquibaseAutoConfiguration 会根据默认配置初始化 SpringLiquibase
  2. SpringLiquibase.afterPropertiesSet()中执行 ChangeSet 文件
  3. 第一次跑 ChangeSets 的时候,会在数据库中自动创建两个表databasechangelogdatabasechangeloglock

因此我们可以认为一个 SpringLiquibase 执行为一个模块。

引入多模块管理时,基于上节文件管理规范,我们基于模块管理再做下调整。

resources
  |-liquibase
    |-user
    | |- master.xml
    | |- release.1.0.0
    | | |- release.xml
    | | |- user.xml -- 用户相关表ChangeSet
    | | |- user.csv -- 用户初始化数据
    | | |- company.xml -- 公司相关表ChangeSet
    | |- release.1.1.0
    | | |- release.xml
    | | |- ...
    |- order
    | |- master.xml
    | |- release.1.0.0
    | | |- ...

如何在一个Spring Boot运行多个SpringLiquibase呢?

1、禁用Spring Boot自动运行Liquibase。

# application.properties
# spring boot 2以上
spring.liquibase.enabled=false
# spring boot 2以下
liquibase.enabled=false

2、修改配置项

@Configuration
public class LiquibaseConfiguration() {

    /**
     *  用户模块Liquibase   
     */
    @Bean
    public SpringLiquibase userLiquibase(DataSource dataSource) {
        SpringLiquibase liquibase = new SpringLiquibase();
        // 用户模块Liquibase文件路径
        liquibase.setChangeLog("classpath:liquibase/user/master.xml");
        liquibase.setDataSource(dataSource);
        liquibase.setShouldRun(true);
        liquibase.setResourceLoader(new DefaultResourceLoader());
        // 覆盖Liquibase changelog表名
        liquibase.setDatabaseChangeLogTable("user_changelog_table");
        liquibase.setDatabaseChangeLogLockTable("user_changelog_lock_table");
        return liquibase;
    }
    /**
     *  订单模块Liquibase   
     */
    @Bean
    public SpringLiquibase orderLiquibase() {
      SpringLiquibase liquibase = new SpringLiquibase();
      liquibase.setChangeLog("classpath:liquibase/order/master.xml");
      liquibase.setDataSource(dataSource);
      liquibase.setShouldRun(true);
      liquibase.setResourceLoader(new DefaultResourceLoader());
      liquibase.setDatabaseChangeLogTable("order_changelog_table");
      liquibase.setDatabaseChangeLogLockTable("order_changelog_lock_table");
      return liquibase;
    }
}
Liquibase命令

liquibase命令详解

对应在 IDEA 中的位置如下图所示:

liquibase命令

changelog文件

变更集 changeset 是通过 author + id 的方式来保证唯一性

changelog文件

<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<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.6.xsd">
   <!--第一种标签建表方式-->
  <changeSet author="future_zwp (generated)" id="reference-2019082600-00" context="team2,uat,prod">
        <createTable tableName="personal_bank_swift">
            <column name="id" type="serial">
                <constraints primaryKey="true"/>
            </column>
            <column name="bank_code" type="text" remarks="银行编码"></column>
            <column name="clearing_code" type="text" ></column>
            <column name="swift_code" type="text" ></column>
            <column name="create_by" type="text" ></column>
            <column name="created_at" type="timestamp"></column>
            <column name="updated_by" type="text" ></column>
            <column name="updated_at" type="timestamp"></column>
            <column name="pt" type="text"></column>
        </createTable>
        <rollback>
            <dropTable tableName="personal_bank_swift"/>
        </rollback>
    </changeSet>
 
    <changeSet author="future_zwp (generated)" id="reference-2019082600-01" context="team2,uat,prod">
        <createIndex indexName="idx_bank_info_bank_clearing" tableName="personal_bank_swift">
            <column name="bank_code"/>
            <column name="clearing_code"/>
        </createIndex>
    </changeSet>
 
    <changeSet author="future_zwp (generated)" id="reference-2019082600-02" context="team2,uat,prod">
        <createIndex indexName="idx_personal_bank_swift_swift_code" tableName="personal_bank_swift">
            <column name="swift_code"/>
        </createIndex>
    </changeSet> 
  
   <!--第二种sql建表方式,所有的sql语句都支持,学习成本低,更灵活-->
  <changeSet author="zhaowenpeng" id="reference-2019082600-03" context="team2,uat,prod">
        <sql splitStatements="true">
            drop table if exists personal_bank_swift;
 
            create table personal_bank_swift
            (
              id serial primary key,
            bank_code     text,
            clearing_code text,
            swift_code    text,
            create_by     text,
            create_at     timestamp(6),
            updated_by    text,
            updated_at    timestamp(6)
            );
 
            comment on column personal_bank_swift.bank_code
            is '银行编码';
 
            create index idx_bank_info_bank_clearing on personal_bank_swift(bank_code,clearing_code);
            create index idx_personal_bank_swift_swift_code on personal_bank_swift(swift_code);
        </sql>
    </changeSet>
  
   <!--引用sql文件-->
   <changeSet author="hresh" id="reference-2019082600-04" context="team2,uat,prod">
        <sqlFile  path="sql/init-personal_bank_swift.sql"></sqlFile>
    </changeSet>
</databaseChangeLog>
默认表

第一次执行完成后目标数据库会多出两张表:

  • DATABASECHANGELOG 表
  • DATABASECHANGELOGLOCK表

1、databasechangelog

Liquibase 使用 databasechangelog 表来跟踪已运行的changeSet。

该表将每个更改设置作为一行进行跟踪,由存储changelog文件的路径的id、author和filename列的组合标识。

请添加图片描述

2、databasechangeloglock

Liquibase 使用 databasechangeloglock 表确保一次只运行一个 Liquibase 实例。

因为Liquibase 只是从 databasechangelog 表读取以确定需要运行的changeSet,因此,如果同时对同一数据库执行多个 Liquibase实例,则会发生冲突。如果多个开发人员使用相同的数据库实例,或者集群中有多个服务器在启动时自动运行 Liquibase,则可能会发生这种情况。

databasechangeloglock表字段详解

如果 Liquibase 未干净地退出,则锁住的行可能会保留为锁定状态。您可以通过运行UPDATE DATABASECHANGELOGLOCK SET LOCKED=0清除当前锁

总结

关于 Liquibase 还有很多知识点需要学习,本文只是简单地带大家认识一下它,不真正使用还是无法理解它的作用,所以下一篇文章我们将实操一个项目,来为大家演示 Liquibase 的功能。

参考文献

Spring Boot使用Liquibase最佳实践

LiquiBase 管理数据库变更实践

liquibase使用教程

Liquibase的基本使用说明

liquibase的changelog详解

liquibase yaml命令参考大全

数据库变更管理:Flyway & Liquibase

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

数据库变更管理:Liquibase or Flyway 的相关文章

  • 【计算机毕业设计】病房管理系统

    当下 如果还依然使用纸质文档来记录并且管理相关信息 可能会出现很多问题 比如原始文件的丢失 因为采用纸质文档 很容易受潮或者怕火 不容易备份 需要花费大量的人员和资金来管理用纸质文档存储的信息 最重要的是数据出现问题寻找起来很麻烦 并且修改
  • 【计算机毕业设计】出租车管理系统

    现代经济快节奏发展以及不断完善升级的信息化技术 让传统数据信息的管理升级为软件存储 归纳 集中处理数据信息的管理方式 本出租车管理系统就是在这样的大环境下诞生 其可以帮助管理者在短时间内处理完毕庞大的数据信息 使用这种软件工具可以帮助管理人
  • 【计算机毕业设计】校园体育赛事管理系统

    身处网络时代 随着网络系统体系发展的不断成熟和完善 人们的生活也随之发生了很大的变化 人们在追求较高物质生活的同时 也在想着如何使自身的精神内涵得到提升 而读书就是人们获得精神享受非常重要的途径 为了满足人们随时随地只要有网络就可以看书的要
  • 【计算机毕业设计】线上招聘问答系统

    计算机网络发展到现在已经好几十年了 在理论上面已经有了很丰富的基础 并且在现实生活中也到处都在使用 可以说 经过几十年的发展 互联网技术已经把地域信息的隔阂给消除了 让整个世界都可以即时通话和联系 极大的方便了人们的生活 所以说 线上招聘问
  • 软件测试/测试开发/全日制/测试管理丨Redis内存数据库

    Redis是一种开源 内存中的数据结构存储系统 它提供了高性能 灵活性和丰富的数据结构 以下是Redis内存数据库的基本介绍 键值存储 Redis基于键值对的存储模型 其中每个键都与一个特定的值相关联 这种简单的数据模型使其易于使用和理解
  • 38条Web测试经验分享

    1 页面链接检查 每一个链接是否都有对应的页面 并且页面之间切换正确 可以使用一些工具 如LinkBotPro File AIDCS HTML Link Validater Xenu等工具 LinkBotPro不支持中文 中文字符显示为乱码
  • 通俗易懂,十分钟读懂DES,详解DES加密算法原理,DES攻击手段以及3DES原理

    文章目录 1 什么是DES 2 DES的基本概念 3 DES的加密流程 4 DES算法步骤详解 4 1 初始置换 Initial Permutation IP置换 4 2 加密轮次 4 3 F轮函数 4 3 1 拓展R到48位 4 3 2
  • 基于java的饮食分享平台系统设计与实现

    基于java的饮食分享平台系统设计与实现 I 引言 A 研究背景和动机 近年来 随着人们生活水平的提高和健康意识的增强 饮食健康已经成为越来越多人的关注焦点 因此 一个方便快捷的饮食分享平台就显得尤为重要 基于Java的饮食分享平台系统设计
  • 深入了解 Python MongoDB 操作:排序、删除、更新、结果限制全面解析

    Python MongoDB 排序 对结果进行排序 使用 sort 方法对结果进行升序或降序排序 sort 方法接受一个参数用于 字段名 一个参数用于 方向 升序是默认方向 示例 按名称按字母顺序对结果进行排序 import pymongo
  • 【计算机毕业设计】电商个性化推荐系统

    伴随着我国社会的发展 人民生活质量日益提高 于是对电商个性化推荐进行规范而严格是十分有必要的 所以许许多多的信息管理系统应运而生 此时单靠人力应对这些事务就显得有些力不从心了 所以本论文将设计一套电商个性化推荐系统 帮助商家进行商品信息 在
  • 【计算机毕业设计】北工国际健身俱乐部

    本系统为会员而设计制作北工国际健身俱乐部 旨在实现北工国际健身俱乐部智能化 现代化管理 本北工国际健身俱乐部管理自动化系统的开发和研制的最终目的是将北工国际健身俱乐部的运作模式从手工记录数据转变为网络信息查询管理 从而为现代管理人员的使用提
  • 【ES6】解构语句中的冒号(:)

    在解构赋值语法中 冒号 的作用是为提取的字段指定一个新的变量名 让我们以示例 const billCode code version route query 来说明 billCode code version 表示从 route query
  • 每日变更的最佳实践

    在优维公司内部 我们采用发布单的方式进行每天的应用变更管理 这里给各位介绍优维的最佳实践 变更是需要多角色合作的 而且他是整体研发流程的一部分 在优维内部 我们坚持每日变更 打通开发环节到最终发布上线的全过程 在保证质量的前提下 尽可能提升
  • 添加对旧变更日志文件的更改。液体碱

    我有很多包含数据库初始数据的变更日志文件 之前所有表都位于 Postgres 公共模式中 但现在我已将它们分布在不同模式之间 以便初始数据的更改无法到达表 我可以用初始数据更改所有旧文件并添加 schemaName my schema 还是
  • 如何在 LiquiBase 变更集中构建 WHERE 子句

    我如何以 LiquiBase 表示法定义变更集 以更新带有 AND 的 WHERE 子句的表列
  • 在 Liquibase 中添加复合唯一约束

    我正在创建一个包含 3 列的链接表 id 产品 id 锦标赛 id 向 id 列添加 uniqueConstraint 很简单 但我想确保任何一对 product id tournament id 都是唯一的 Liquibase org 上
  • jhipster liquibase 不更新数据库

    我正在尝试添加一个新实体 但不使用完整的热重载 因此我创建了一个 db changelog 002 xml 文件 其中包含要在文件的变更集中创建的新表 然后我运行了 mvn spring boot run 但我的数据库没有使用新表进行更新
  • 有没有办法以正确的顺序生成 Liquibase 数据?

    我正在使用 Liquibase 对现有数据库进行版本控制 所以我使用 liquibase logLevel debug driver com mysql jdbc Driver classpath lib mysql connector j
  • 如果计算机未连接到互联网,Liquibase 将失败

    当我尝试启动 Liquibase 使用 Karaf 时 出现以下错误 无法读取架构文档http www liquibase org xml ns dbchangelog dbchangelog 3 0 xml http www liquib
  • Liquibase 从 JPA 实体生成变更日志

    我有一个 Spring boot spring data jpa 项目 带有一个父模块和三个子模块 我的模块之一负责我的 JPA 实体 我需要使用该实体的 liquibase 生成一个 xml 变更日志 在我的 liquibase prop

随机推荐

  • android httpClient 支持HTTPS的2种处理方式

    项目中Android https或http请求地址重定向为HTTPS的地址 相信很多人都遇到了这个异常 无终端认证 javax net ssl SSLPeerUnverifiedException No peer certificate 1
  • YoloV4训练自己的数据集

    YoloV4训练自己的数据集 1 建立工作文件夹 2 准备训练数据集 3 修改配置文件 4 Anchor Box先验框聚类分析与修改 5 训练自己的数据集 6 测试训练出来的网络模型 7 性能统计 1 建立工作文件夹 新建一个项目文件夹 用
  • STM32/AMP32F407进入低功耗待机模式后立马被唤醒的解决办法

    最近项目用到低功耗 但是调试发现进入待机就被唤醒的问题 清除WU SB两个唤醒标志位 也依然被立马唤醒一次 进入待机模式 HAL PWR EnterSTANDBYMode 通过极海的数据手册终于发现 我们在使能WAKE UP PA 0唤醒脚
  • 【Linux】进程描述符

    linux进程管理 1 进程描述符 进程描述符 Linux使用进程描述符数据结构记录现场信息 然后给予进程描述符管理进程 包括进程的创建 调度 消亡等操作 进程除了包括运行着的程序 还包括系统资源 当前CPU现场 调度信息 进程间关系等 记
  • One PUNCH Man——激活函数和梯度消失/爆炸

    文章目录 什么是激活函数 激活函数介绍 梯度消失 爆炸 首先推荐一个写公式的网站 https private codecogs com latex eqneditor php 什么是激活函数 如下图 在神经元中 输入的 inputs 通过加
  • FlatBuffers在Java中的使用

    1 去maven仓库下载官网库flatbuffers java 1 7 0 1 jar 地址 点击打开链接 2 编写fbs文件 chat fbs namespace Proto 聊天频道 enum ChatChannel byte SYST
  • 利用Logstash plugins做更多的事情

    1 引言 之前一篇文章 Logstash 介绍及linux下部署 我们实现了logstash的安装以及简单的控制台标准输入输出测试 那么logstash能不能做更多的事情呢 答案是肯定的 logstash就是为了处理日志数据而生的 一个最直
  • mysql下出现Unknown column 'xx' in 'on clause'的完全解决方法

    mysql下出现Unknown column xx in on clause 的完全解决方法 在项目中执行查询无结果 在数据库运行sql报错 Unknown column xx in on clause 百度过后找到这个文章并完全解决了问题
  • 欠拟合和过拟合

    过拟合 定义 具体表现就是最终模型在训练集上效果好 在测试集上效果差 模型泛化能力弱 具体表现就是最终模型在训练集上效果好 在测试集上效果差 模型过于复杂 过拟合的原因 训练数据中噪音干扰过大 使得学习器认为部分噪音是特征从而扰乱学习规则
  • Nginx二级项目配置

    Nginx二级项目服务页面部署 应用场景 比如一个项目需要一个正常的生产服务的地址在根目录 现在需要一个后台管理项目可以部署在 admin 的路径下 需要帮助文档的页面可以部署在 help nginx conf 配置 location ma
  • 【SQL注入-08】二次注入案例—以sqli-labs-less24为例

    目录 1 二次注入概述 1 1 定义 1 2 思路 2 二次注入案例 2 1 实验平台 2 2 实验目标 2 3 具体注入过程 2 3 1 注入前准备 2 3 2 确定目标账户admin 2 3 3 第一次注入 2 3 4 第二次注入 2
  • eos bp节点 超级节点搭建

    https github com nebulaprotocol 这个网址里面有一个 fake terminal website 比较有意思 可以看看示例 https bp nebulaprotocol com 搭建eos BP节点 环境搭建
  • 家政服务小程序制作攻略揭秘

    想要打造一个家政服务小程序 但是又不懂编程和设计 不用担心 下面将为你详细介绍如何利用第三方平台 从零开始打造一个家政服务小程序 首先 你需要找到一个适合的第三方平台 例如乔拓云网 在乔拓云网的 轻应用小程序 中 点击 去管理 你就可以进入
  • 回顾2021,展望2022

    2021 这一年最大的收获是孕育了一个聪明漂亮机灵的小家伙 这一年我虚岁28岁 和爱的人有了爱的结晶 东哥各方面都挺好的 我们都不是圣人 都是能力有限的普通人 但他在尽其所能的对我好 我不是万能的人 但也独立坚强 之后一个人带娃的日子适应的
  • LaTeX公式中指定某些字母或符号为正体

    m rm G 显示效果为
  • I/O 函数/缓存和字节流、占位符、getchar(),putchar()

    I O 函数 C 语言提供了一些函数 用于与外部设备通信 称为输入输出函数 简称 I O 函数 输入 import 指的是获取外部数据 输出 export 指的是向外部传递数据 缓存和字节流 严格地说 输入输出函数并不是直接与外部设备通信
  • 从零开始学C++之异常(三):异常与继承、异常与指针、异常规格说明

    一 异常与继承 如果异常类型为C 的类 并且该类有其基类 则应该将派生类的错误处理程序放在前面 基类的错误处理程序放在后面 include
  • python3.5源码分析-启动与虚拟机

    Python3源码分析 本文环境python3 5 2 参考书籍 lt
  • 虚幻引擎游戏开发过程中,游戏鼠标如何双击判定?

    UE虚幻引擎对于游戏开发者来说都不陌生 市面上有47 主机游戏使用虚幻引擎开发游戏 作为是一款游戏的核心动力 它的功能十分完善 囊括了场景制作 灯光渲染 动作镜头 粒子特效 材质蓝图等 本文介绍了虚幻引擎游戏开发过程中游戏鼠标双击判定 一起
  • 数据库变更管理:Liquibase or Flyway

    从零打造项目 系列文章 工具 比MyBatis Generator更强大的代码生成器 ORM框架选型 SpringBoot项目基础设施搭建 SpringBoot集成Mybatis项目实操 SpringBoot集成MybatisPlus项目实