在项目迭代开发中,难免会有更新数据库 Schema 的情况,比如添加新表、在表中增加字段或者删除字段等,那么当我对数据库进行一系列操作后,如何快速地在其他同事的电脑上同步?如何在测试/生产服务器上快速同步?

每次发版的时候,由于大家都可能有 sql 更改情况,这样就会有以下痛点:

  • 忘记某些 sql 修改

  • 每个开发人员的 sql 的执行顺序问题

  • 重复更新

  • 需要手动去数据库执行脚本

以上问题以及痛点可以通过 Flyway 工具来解决,Flyway 可以实现自动化的数据库版本管理,并且能够记录数据库版本更新记录。

Flyway 简介

Flyway 是独立于数据库的应用、管理并跟踪数据库变更的数据库版本管理工具。用通俗的话讲,Flyway 可以像 Git 管理不同人的代码那样,管理不同人的 sql 脚本,从而做到数据库同步,更多的信息可以在 Flyway 的官网上进行阅读学习。

另外 Flyway 支持很多关系数据库,具体如下所示:

下面我们在 Spring Boot 中集成 Flyway 来实现数据库版本控制。

Spring Boot 集成 Flyway

首先创建一个 SpringBoot 项目,然后在 pom.xml 加入如下依赖集成 Flyway:

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

然后在 application.yml 中写入 mysql 的配置及 Flyway 的相关配置(Flyway locations 默认读取当前项目下的 resources/db/migration 目录)

spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/test?serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=123spring.flyway.locations=classpath:/db/migration/

接下来,在 resources/db/migration 目录下创建需要执行的 SQL 脚本即可。

其中,SQL 脚本命名规范如下:

  • Prefix 前缀:V 代表版本迁移,U 代表撤销迁移,R 代表可重复迁移

  • Version 版本号:版本号通常 . 和整数组成

  • Separator 分隔符:固定由两个下划线 __ 组成

  • Description 描述:由下划线分隔的单词组成,用于描述本次迁移的目的

  • Suffix 后缀:如果是 SQL 文件那么固定由 .sql 组成,如果是基于 Java 类则默认不需要后缀

那么,我们按照命名规范在 resources/db/migration 目录下,创建 V1.0__init_db.sql SQL 迁移脚本,具体内容如下:

DROP TABLE IF EXISTS `user` ;CREATE TABLE `user` (`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',`name` varchar(20) NOT NULL COMMENT '姓名',`age` int(11) DEFAULT NULL COMMENT '年龄',PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;INSERT INTO `user` (`id`, `name`, `age`) VALUES ('1', 'wupx', '18');

最后启动项目,执行日志如下所示:

2020-05-07 12:41:29.126  INFO 13732 --- [           main] o.f.c.internal.license.VersionPrinter    : Flyway Community Edition 5.2.4 by Boxfuse
2020-05-07 12:41:29.236  INFO 13732 --- [           main] o.f.c.internal.database.DatabaseFactory  : Database: jdbc:mysql://localhost:3306/test (MySQL 5.5)
2020-05-07 12:41:29.287  INFO 13732 --- [           main] o.f.core.internal.command.DbValidate     : Successfully validated 1 migration (execution time 00:00.009s)
2020-05-07 12:41:29.330  INFO 13732 --- [           main] o.f.c.i.s.JdbcTableSchemaHistory         : Creating Schema History table: `test`.`flyway_schema_history`
2020-05-07 12:41:29.479  INFO 13732 --- [           main] o.f.core.internal.command.DbMigrate      : Current version of schema `test`: << Empty Schema >>
2020-05-07 12:41:29.480  INFO 13732 --- [           main] o.f.core.internal.command.DbMigrate      : Migrating schema `test` to version 1.0 - init db
2020-05-07 12:41:29.481  WARN 13732 --- [           main] o.f.c.i.s.DefaultSqlScriptExecutor       : DB: Unknown table 'user' (SQL State: 42S02 - Error Code: 1051)
2020-05-07 12:41:29.631  INFO 13732 --- [           main] o.f.core.internal.command.DbMigrate      : Successfully applied 1 migration to schema `test` (execution time 00:00.301s)

从启动日志中可以看出,Flyway 监测到需要运行版本脚本来初始化数据库,因此执行了 V1.0__init_db.sql 脚本,从而创建了 user 表,另外还自动创建了 flyway_schema_history 表,用于记录所有版本演化和状态,其表结构如下(以 MySQL 为例):

Field Type Null Key Default
version_rank int(11) NO MUL NULL
installed_rank int(11) NO MUL NULL
version varchar(50) NO PRI NULL
description varchar(200) NO NULL
type varchar(20) NO NULL
script varchar(1000) NO NULL
checksum int(11) YES NULL
installed_by varchar(100) NO NULL
installed_on timestamp NO CURRENT_TIMESTAMP
execution_time int(11) NO NULL
success tinyint(1) NO MUL NULL

查询 flyway_schema_history 表,发现增加了一条版本号为 1.0 的,使用 V1.0__init_db.sql 迁移脚本的记录。

mysql> SELECT * FROM flyway_schema_history;
+----------------+---------+-------------+------+-------------------+------------+--------------+---------------------+----------------+---------+
| installed_rank | version | description | type | script            | checksum   | installed_by | installed_on        | execution_time | success |
+----------------+---------+-------------+------+-------------------+------------+--------------+---------------------+----------------+---------+
|              1 | 1.0     | init db     | SQL  | V1.0__init_db.sql | 1317299633 | root         | 2020-05-07 12:41:29 |             97 |       1 |
+----------------+---------+-------------+------+-------------------+------------+--------------+---------------------+----------------+---------+

再去查询 user 表,发现 sql 脚本中的数据也插入成功了。

mysql> SELECT * FROM user;
+----+------+-----+
| id | name | age |
+----+------+-----+
|  1 | wupx |  18 |
+----+------+-----+

接下来再次运行项目,结果如下:

2020-05-07 15:34:49.843  INFO 41880 --- [           main] o.f.c.internal.license.VersionPrinter    : Flyway Community Edition 5.2.4 by Boxfuse
2020-05-07 15:34:49.981  INFO 41880 --- [           main] o.f.c.internal.database.DatabaseFactory  : Database: jdbc:mysql://localhost:3306/test (MySQL 5.5)
2020-05-07 15:34:50.036  INFO 41880 --- [           main] o.f.core.internal.command.DbValidate     : Successfully validated 1 migration (execution time 00:00.013s)
2020-05-07 15:34:50.043  INFO 41880 --- [           main] o.f.core.internal.command.DbMigrate      : Current version of schema `test`: 1.0
2020-05-07 15:34:50.043  INFO 41880 --- [           main] o.f.core.internal.command.DbMigrate      : Schema `test` is up to date. No migration necessary.

从日志中可以看出,Flyway 发现一个迁移脚本,也就是 V1.0__init_db.sql,经过判断已经到达最新版本 1.0,无需执行迁移。

接下来,我们在 V1.0__init_db.sql 迁移脚本中添加一条 INSERT 操作:INSERT INTOuser(id,name,age) VALUES ('2', 'huxy', '18'); ,再次启动项目,会报如下错误:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'flywayInitializer' defined in class path resource [org/springframework/boot/autoconfigure/flyway/FlywayAutoConfiguration$FlywayConfiguration.class]: Invocation of init method failed; nested exception is org.flywaydb.core.api.FlywayException: Validate failed: Migration checksum mismatch for migration version 1.0
-> Applied to database : 1317299633
-> Resolved locally    : -1582367361

这个错误的原因就是 Flyway 会给脚本计算一个 checksum 保存在数据库中,用于在之后运行过程中对比 sql 文件是否有变化,如果发生了变化,则会报错,也就防止了误修改脚本导致发生问题。

总结

Flyway 可以有效改善数据库版本管理方式,并且是一款 Java 开源的数据库迁移管理工具,具有轻便小巧的特点,可以无门槛快速集成到项目中,如果项目中还未使用,不防尝试一下,想了解更多的可以去官网查看文档学习。

本文的完整代码在 https://github.com/wupeixuan/SpringBoot-Learndatabase-version-control 目录下。

留言讨论

最好的关系就是互相成就,大家的在看、转发、留言三连就是我创作的最大动力。

参考

https://flywaydb.org/

https://github.com/wupeixuan/SpringBoot-Learn

●ZooKeeper 入门看这篇就够了

●Nginx 了解一下?

●你真的了解 volatile 关键字吗?

Spring Boot 集成 Flyway 实现数据库版本控制相关推荐

  1. flyway版本号_Spring Boot 集成 Flyway 实现数据库版本控制

    在项目迭代开发中,难免会有更新数据库 Schema 的情况,比如添加新表.在表中增加字段或者删除字段等,那么当我对数据库进行一系列操作后,如何快速地在其他同事的电脑上同步?如何在测试/生产服务器上快速 ...

  2. Spring Boot集成Debezium监控数据库变化

    看这篇文章之前,建议先看这篇文章,主要是采用数据库的binlog进行监听 mysql实时监听canal+kafka_怪只怪满眼尽是人间烟火-CSDN博客1.首先安装mysql2.然后安装kafka然后 ...

  3. Spring Boot集成Quartz动态实现数据库任务

    1. Quartz简介 1.1. 什么是Quartz Quartz是一个开源的任务调度框架.作用是基于定时.定期的策略来执行任务. 它是OpenSymphony开源组织在Job scheduling领 ...

  4. 6.3 Spring Boot集成mongodb开发

    6.3 Spring Boot集成mongodb开发 本章我们通过SpringBoot集成mongodb,Java,Kotlin开发一个极简社区文章博客系统. 0 mongodb简介 Mongo 的主 ...

  5. Spring Boot 集成 Swagger 生成 RESTful API 文档

    原文链接: Spring Boot 集成 Swagger 生成 RESTful API 文档 简介 Swagger 官网是这么描述它的:The Best APIs are Built with Swa ...

  6. Spring Boot集成JPA的Column注解命名字段无效的问题

    偶然发现,Spring Boot集成jpa编写实体类的时候,默认使用的命名策略是下划线分隔的字段命名. Spring Boot版本:1.5.4.release 数据表: id int, userNam ...

  7. Kafka 入门和 Spring Boot 集成

    2019独角兽企业重金招聘Python工程师标准>>> Kafka 入门和 Spring Boot 集成 概述 kafka 是一个高性能的消息队列,也是一个分布式流处理平台(这里的流 ...

  8. Spring Boot 集成 Druid 监控数据源

    关注"Java后端技术全栈" 回复"面试"获取全套大厂面试资料 Druid 介绍 Druid 是阿里巴巴开源平台上的一个项目,整个项目由数据库连接池.插件框架和 ...

  9. Spring Boot 集成 Mybatis 实现双数据源

    转载自   Spring Boot 集成 Mybatis 实现双数据源 这里用到了Spring Boot + Mybatis + DynamicDataSource配置动态双数据源,可以动态切换数据源 ...

最新文章

  1. 2020年人工神经网络第二次作业-参考答案第六题
  2. JavaScript -- throw、try 和 catch
  3. C#测试程序运行时间
  4. 安装oracle sqldeveloper
  5. 服务器删除网站文章,如何一次性删除wordpress所有文章
  6. Tkinter的Scrollba组件
  7. android media_rw sdcard_rw,大约Android 了解权限管理
  8. 酷酷实训计划及测试计划
  9. [渝粤教育] 中国地质大学 自动控制原理 复习题 (2)
  10. java解析bmp文件
  11. CCIE-LAB-SDN-第三篇-SD-WAN
  12. 从一套表达和通路数据学习常见的绘图展示方式和报错处理
  13. 计算机设置成一个网络,同一个路由器上的电脑怎么设置成局域网连网打 – 手机爱问...
  14. STM32工作笔记0053---STM32串口寄存器库函数配置方法+串口通信实例
  15. HTML5 学习(1) -- 介绍
  16. 【链表】剑指offer:从尾到头打印链表
  17. 串口通信USART的波特率误差计算GD32、STM32
  18. h5调用手机相机和录音机_html5 调用手机摄像头以及录音的方法
  19. css鼠标hover的时候变成小手型
  20. 电脑桌面美化教程,强迫症福利

热门文章

  1. 腾讯QQ的聊天记录中的图片记录造假
  2. 小兔鲜静态页面(Html5+CSS3)
  3. Py之tensorflow-federated:tensorflow-federated的简介、安装、使用方法之详细攻略
  4. Django—DetailView
  5. 1号店连添头都算不上,京东与沃尔玛,谁才是接盘侠
  6. 电子竞技行业所面临的四大攻击威胁
  7. nginx禁止高频ip访问
  8. php 指纹登录,window_win10系统中怎么设置指纹登陆?,现在很多电脑已经直接升级到 - phpStudy...
  9. 告别简陋,让Arduino开发变得高大上——MS VSCode体验
  10. 喜欢XP,就会喜欢Windows 7