4

什么是Flyway

Flyway是一款开源的数据库版本管理工具,应用程序不断演进一样,数据库的结构也需要跟着变化,这可能涉及添加新表、修改表结构或者插入初始数据等等。
大白话:flyway就是一款数据库迁移工具。

为什么要使用Flyway

我们的代码都是提交在git上,可以进行版本控制。数据库呢?因为使用ddl-auto = update,数据库结构的变更是隐式的。别的开发人员根本不知道更改了。虽说手动运行、维护 SQL 脚本,每次开发完后还要跟团队的成员说我对sql进行了更改,而且中间还不能出差错,万一中间出了差错,想回到之前的某个版本、某个状态。这个时候flyway就解决了这个问题。
flyway,可以跟踪数据库版本的改变,明确数据库处于那个状态,并且以确定的方式从数据库的当前版本迁移到新版本。

简单例子:
现在有一张用户表,里面有name、xingbie字段,现在想更改xingbie字段名称,改成:sex, 如果使用ddl-auto = update,xingbie字段里面的数据并不会给到sex字段,并且还会新创建sex字段,需要手动维护,使用flyway,就可以直接更改xingbie为sex,做好记录,不需要手动去维护了。
image.png

Flyway的工作机制

flyway在第一次执行时,会默认创建 flyway_schema_history存放这个历史版本信息的表(如果没有设置表名的话)

image.png

然后flyway会去db/migration下面扫描文件,获取文件名,并解析版本号。
在然后去schema_version_history表里面找对应的版本执行信息,如果你的文件版本号大于数据库记录版本,就执行脚本。否则就忽略。

image.png
image.png

flyway_schema_history 的字段如下:

//字段名:
installed_rank //迁移的顺序
version //版本号
description //描述
type //类型
script //迁移的文件名
checksum //迁移内容的校验
installed_by //迁移的用户
installed_on //迁移被执行的时间戳
execution_time //执行过程的时间(过程时间)
success //成功: 1 、 失败:0

命名规范

image.png

Prefix 大写字母 "V" 开头,表示迁移
Version 标识版本号, 由一个或多个数字构成, 数字之间的分隔符可用点 . 或下划线 _
Separator 可配置, 用于分隔版本标识与描述信息, 默认为两个下划线 __
Description 描述信息, 文字之间可以用下划线 _ 或空格 分隔
Suffix 可配置, 后续标识, 默认为 .sql,表示sql脚本文件
例:
V1.6__update_training_notice.sql
V 表示迁移
1.6版本号
-- 分隔符
update_training_notice 描述
sql 脚本文件

Springboot 和 flyway结合使用

安装依赖

<dependency>
            <groupId>org.flywaydb</groupId>
            <artifactId>flyway-core</artifactId>
</dependency>

配置

spring:
  config:
    activate:  //激活配置
      on-profile: dev  //当profile为dev时激活配置
  datasource:  //对mysql进行连接
    url: "jdbc:mysql://localhost:3312/healthTraining?characterEncoding=utf-8" 
    username: "root"  
    password: "****"
    driver-class-name: com.mysql.cj.jdbc.Driver // 数据库驱动类名
  jpa:
    generate-ddl: true  # //是否自动生成DDL语句
    show-sql: false  # //是否显示SQL语句
    properties:  
      hibernate:  //使用mysql5.7
        dialect: "org.hibernate.dialect.MySQL57Dialect"
      ddl-auto: validate  启用校验验证模式
  flyway:  
    enabled: true  //是否启用Flyway

当在开发的时候,进行validate 改成 updata, show-sql: false 改成 ture,显示sql语句(后面会有用)。
当使用@Entity会将将一个 Java 类标记为一个 JPA 实体。JPA 实体对应数据库中的表。可以看到创建了exam表

image.png

当开发完后,恢复到:validate,然后创建了sql文件
V3.1.32__add_exam.sql, 然后把修改的sql语句添加到sql脚本文件中

image.png

出现问题:

此时就出现了报错,4200 代表sql的语法错误
image.png
那么此时 flyway_schema_history 表就会记录这次迁移失败。
image.png

对sql文件修改后:
exam 已存在存在,创建失败了 图下:
1713254033468_E3B7DC62-BE86-41d8-B1CA-E3C29FDB28A8.png
原因: V3.1.32是最新版本,那么里面的sql语句肯定会去执行,但是,JPA已经帮我在创建了exam表。那么在次创建就会报错。
解决:进入删除 exam表就好了。

最重要的一点:
之前记录迁移失败的记录要删除,不然会出现:

Detected failed migration to version 3.1.32 (add exam). Please remove any half-completed changes then run repair to fix the schema history.

image.png

原因:迁移操作失败时,数据库迁移工具会将失败的迁移标记为已执行,但由于迁移失败,数据库结构可能不完全符合预期,因此,通过删除失败的迁移记录,可以重新执行迁移操作,并确保数据库结构与应用程序的期望一致。
刪除后,再次启动就启动成功了,这个时候你就可以push你的代码了。

总结

sql 状态码:
42000、42601:语法错误,
23000:违反约束,
42S01: 表名拼写错误,
42S02:表名不存在


zZ_jie
436 声望9 粉丝

虚心接受问题,砥砺前行。