Spring Boot中使用Flyway来管理数据库版本

久违了的Spring Boot系列,今天抽空更新一篇。之前写过很多篇关于数据访问的文章了,比如下面这些:

  • 使用JdbcTemplate

  • 使用Spring-data-jpa简化数据访问层(推荐)

  • 多数据源配置(一):JdbcTemplate

  • 多数据源配置(二):Spring-data-jpa

  • 使用NoSQL数据库(一):Redis

  • 使用NoSQL数据库(二):MongoDB

  • 整合MyBatis

  • MyBatis注解配置详解

  • 使用事务管理

由于这些文章写的比较早,公众号中没有存档,如果没有读过上面内容的读者,有兴趣的可以通过去我的博客(didispace.com)阅读。还想看更多?戳这里:Spring干货汇总(含Spring Boot与Spring Cloud)

在上面的使用JdbcTemplate一文中,主要通过spring提供的JdbcTemplate实现对用户表的增删改查操作。在实现这个例子的时候,我们事先在MySQL中创建了用户表。创建表的过程我们在实际开发系统的时候会经常使用,但是一直有一个问题存在,由于一个系统的程序版本通过git得到了很好的版本控制,而数据库结构并没有,即使我们通过Git进行了语句的版本化,那么在各个环境的数据库中如何做好版本管理呢?下面我们就通过本文来学习一下在Spring Boot中如何使用Flyway来管理数据库的版本。

Flyway简介

Spring Boot中使用Flyway来管理数据库版本_第1张图片

Flyway是一个简单开源数据库版本控制器(约定大于配置),主要提供migrate、clean、info、validate、baseline、repair等命令。它支持SQL(PL/SQL、T-SQL)方式和Java方式,支持命令行客户端等,还提供一系列的插件支持(Maven、Gradle、SBT、ANT等)。

官方网站:https://flywaydb.org/

本文对于Flyway的自身功能不做过多的介绍,读者可以通过阅读官方文档或利用搜索引擎获得更多资料。下面我们具体说说在Spring Boot应用中的应用,如何使用Flyway来创建数据库以及结构不一致的检查。

动手试一试

下面我们可以通过对使用JdbcTemplate一文中的例子进行加工完成。读者也可以拿任何一个与数据访问相关的工程来做如下内容的实验:

  • 第一步,在 pom.xml中增加flyway的依赖:

    
    
    
    
  1.    org.flywaydb

  2.    flyway-core

  3.    5.0.3

  • 第二步,按Flyway的规范创建版本化的SQL脚本。

  • 在工程的 src/main/resources目录下创建 db目录

  • 在 db目录下创建版本化的SQL脚本 V1__Base_version.sql

    
    
    
    
  1. DROP TABLE IF EXISTS user ;

  2. CREATE TABLE `user` (

  3.  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',

  4.  `name` varchar(20) NOT NULL COMMENT '姓名',

  5.  `age` int(5) DEFAULT NULL COMMENT '年龄',

  6.  PRIMARY KEY (`id`)

  7. ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

  • 第三步,在 application.properties文件中配置Flyway要加载的SQL脚本位置。按第二步创建的结果配置如下:

    
    
    
    
  1. flyway.locations=classpath:/db

  • 第四步,执行单元测试 ApplicationTests,此时我们在日志中可以看到如下信息:

    
    
    
    
  1. INFO 82441 --- [main] o.f.core.internal.util.VersionPrinter    : Flyway Community Edition 5.0.3 by Boxfuse

  2. INFO 82441 --- [main] o.f.c.internal.database.DatabaseFactory  : Database: jdbc:mysql://localhost:3306/test (MySQL 5.7)

  3. INFO 82441 --- [main] o.f.core.internal.command.DbValidate     : Successfully validated 1 migration (execution time 00:00.022s)

  4. INFO 82441 --- [main] o.f.c.i.s.JdbcTableSchemaHistory         : Creating Schema History table: `test`.`flyway_schema_history`

  5. INFO 82441 --- [main] o.f.core.internal.command.DbMigrate      : Current version of schema `test`: << Empty Schema >>

  6. INFO 82441 --- [main] o.f.core.internal.command.DbMigrate      : Migrating schema `test` to version 1 - Base version

  7. WARN 82441 --- [main] o.f.core.internal.sqlscript.SqlScript    : DB: Unknown table 'test.user' (SQL State: 42S02 - Error Code: 1051)

  8. INFO 82441 --- [main] o.f.core.internal.command.DbMigrate      : Successfully applied 1 migration to schema `test` (execution time 00:00.128s)

Flyway监测到需要运行版本脚本来初始化数据库,因此执行了 V1__Base_version.sql脚本,从而创建了user表,这才得以让一系列单元测试(对user表的CRUD操作)通过。

  • 第五步,我们可以继续再执行一下单元测试,此时我们会发现日志输出与之前不同:

    
    
    
    
  1. INFO 83150 --- [main] o.f.core.internal.util.VersionPrinter    : Flyway Community Edition 5.0.3 by Boxfuse

  2. INFO 83150 --- [main] o.f.c.internal.database.DatabaseFactory  : Database: jdbc:mysql://localhost:3306/test (MySQL 5.7)

  3. INFO 83150 --- [main] o.f.core.internal.command.DbValidate     : Successfully validated 1 migration (execution time 00:00.031s)

  4. INFO 83150 --- [main] o.f.core.internal.command.DbMigrate      : Current version of schema `test`: 1

  5. INFO 83150 --- [main] o.f.core.internal.command.DbMigrate      : Schema `test` is up to date. No migration necessary.

由于在第四步的时候,初始化脚本已经执行过,所以这次执行就没有再去执行 V1__Base_version.sql脚本来重建user表。

  • 第六步,我们可以尝试修改一下 V1__Base_version.sql脚本中的name字段长度,然后在运行一下单元测试,此时我们可以得到如下错误:

    
    
    
    
  1. ERROR 83791 --- [main] o.s.boot.SpringApplication               : Application startup failed

  2. 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

  3. -> Applied to database : 466264992

  4. -> Resolved locally    : -270269434

由于初始化脚本的改动,Flyway校验失败,认为当前的 V1__Base_version.sql脚本与上一次执行的内容不同,提示报错并终止程序,以免造成更严重的数据结构破坏。

总结

到这里为止,本文的内容告一段落。由于博文篇幅问题,对于Flyway更细节的使用没有说的太多,本文主要作为敲门砖,帮助和引导正在使用Spring Boot做系统开发的个人或团队在数据库的版本控制上做的更好提供一些思路。至于更深入的应用还请读者自行翻阅官方文档参考和学习。

还想看更多?戳这里:Spring干货汇总(含Spring Boot与Spring Cloud)

本文代码

可以通过下面两个仓库中查阅Chapter3-2-9目录:

  • Github:https://github.com/dyc87112/SpringBoot-Learning/

  • Gitee:https://gitee.com/didispace/SpringBoot-Learning

推荐阅读

缓存穿透、缓存并发、热点缓存之最佳招式

那些有趣又实用的开源人工智能项目 Top 10

自学编程需要注意什么?

IntelliJ IDEA插件系列:五大装逼神器

我最常用的Intellij IDEA快捷键

最好用的 IntelliJ 插件 Top 10


长按指纹

一键关注


点击 “阅读原文” 看看本号其他精彩内容

你可能感兴趣的:(Spring Boot中使用Flyway来管理数据库版本)