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

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

Flyway简介

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的依赖:

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

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

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

在db目录下创建版本化的SQL脚本V1__Base_version.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(5) DEFAULT NULL COMMENT '年龄',
 PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

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

flyway.locations=classpath:/db

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

INFO 82441 --- [main] o.f.core.internal.util.VersionPrinter  : Flyway Community Edition 5.0.3 by Boxfuse
INFO 82441 --- [main] o.f.c.internal.database.DatabaseFactory : Database: jdbc:mysql://localhost:3306/test (MySQL 5.7)
INFO 82441 --- [main] o.f.core.internal.command.DbValidate   : Successfully validated 1 migration (execution time 00:00.022s)
INFO 82441 --- [main] o.f.c.i.s.JdbcTableSchemaHistory     : Creating Schema History table: `test`.`flyway_schema_history`
INFO 82441 --- [main] o.f.core.internal.command.DbMigrate   : Current version of schema `test`: << Empty Schema >>
INFO 82441 --- [main] o.f.core.internal.command.DbMigrate   : Migrating schema `test` to version 1 - Base version
WARN 82441 --- [main] o.f.core.internal.sqlscript.SqlScript  : DB: Unknown table 'test.user' (SQL State: 42S02 - Error Code: 1051)
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操作)通过。

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

INFO 83150 --- [main] o.f.core.internal.util.VersionPrinter  : Flyway Community Edition 5.0.3 by Boxfuse
INFO 83150 --- [main] o.f.c.internal.database.DatabaseFactory : Database: jdbc:mysql://localhost:3306/test (MySQL 5.7)
INFO 83150 --- [main] o.f.core.internal.command.DbValidate   : Successfully validated 1 migration (execution time 00:00.031s)
INFO 83150 --- [main] o.f.core.internal.command.DbMigrate   : Current version of schema `test`: 1
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字段长度,然后在运行一下单元测试,此时我们可以得到如下错误:

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

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
-> Applied to database : 466264992
-> Resolved locally  : -270269434

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

总结

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

本文代码:Github:https://github.com/dyc87112/SpringBoot-Learning/

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

您可能感兴趣的文章:

  • Spring Boot中使用Spring-data-jpa实现数据库增删查改
  • Spring Boot MyBatis 连接数据库配置示例
  • Spring Boot Mysql 数据库操作示例
  • springboot配置内存数据库H2教程详解
  • Spring Boot JDBC 连接数据库示例
  • Spring boot实现数据库读写分离的方法
  • Spring Boot中Redis数据库的使用实例
  • 详解SpringBoot 创建定时任务(配合数据库动态执行)
  • Spring Boot 添加MySQL数据库及JPA实例
时间: 2017-12-31

Spring Boot 添加MySQL数据库及JPA实例

最近在学习Spring Boot,继续前面的学习,这一次我们加入MySQL数据库和JPA. 配置: pom.xml文件 <!-- 添加Mysql和JPA--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dep

Spring Boot MyBatis 连接数据库配置示例

最近比较忙,没来得及抽时间把MyBatis的集成发出来,其实mybatis官网在2015年11月底就已经发布了对SpringBoot集成的Release版本,示例代码:spring-boot_jb51.rar 前面对JPA和JDBC连接数据库做了说明,本文也是参考官方的代码做个总结. 先说个题外话,SpringBoot默认使用 org.apache.tomcat.jdbc.pool.DataSource 现在有个叫 HikariCP 的JDBC连接池组件,据说其性能比常用的 c3p0.tomca

Spring Boot中Redis数据库的使用实例

spring boot对常用的数据库支持外,对nosql 数据库也进行了封装自动化. redis介绍 Redis是目前业界使用最广泛的内存数据存储.相比memcached,Redis支持更丰富的数据结构,例如hashes, lists, sets等,同时支持数据持久化.除此之外,Redis还提供一些类数据库的特性,比如事务,HA,主从库.可以说Redis兼具了缓存系统和数据库的一些特性,因此有着丰富的应用场景.本文介绍Redis在Spring Boot中两个典型的应用场景. 如何使用 1.引入

Spring Boot JDBC 连接数据库示例

文本将对在spring Boot构建的Web应用中,基于MySQL数据库的几种数据库连接方式进行介绍. 包括JDBC.JPA.MyBatis.多数据源和事务. JDBC 连接数据库 1.属性配置文件(application.properties) spring.datasource.url=jdbc:mysql://localhost:3306/test spring.datasource.username=root spring.datasource.password=123456 sprin

springboot配置内存数据库H2教程详解

业务背景:因soa系统要供外网访问,处于安全考虑用springboot做了个前置模块,用来转发外网调用的请求和soa返回的应答.其中外网的请求接口地址在DB2数据库中对应专门的一张表来维护,要是springboot直接访问数据库,还要专门申请权限等,比较麻烦,而一张表用内置的H2数据库维护也比较简单,就可以作为替代的办法. 环境:springboot+maven3.3+jdk1.7 1.springboot的Maven工程结构 说明一下,resource下的templates文件夹没啥用.我忘记

详解SpringBoot 创建定时任务(配合数据库动态执行)

序言:创建定时任务非常简单,主要有两种创建方式:一.基于注解(@Scheduled) 二.基于接口(SchedulingConfigurer). 前者相信大家都很熟悉,但是实际使用中我们往往想从数据库中读取指定时间来动态执行定时任务,这时候基于接口的定时任务就大派用场了. 一.静态定时任务(基于注解) 基于注解来创建定时任务非常简单,只需几行代码便可完成. @Scheduled 除了支持灵活的参数表达式cron之外,还支持简单的延时操作,例如 fixedDelay ,fixedRate 填写相应

Spring Boot中使用Spring-data-jpa实现数据库增删查改

在实际开发过程中,对数据库的操作无非就"增删改查".就最为普遍的单表操作而言,除了表和字段不同外,语句都是类似的,开发人员需要写大量类似而枯燥的语句来完成业务逻辑. 为了解决这些大量枯燥的数据操作语句,我们第一个想到的是使用ORM框架,比如:Hibernate.通过整合Hibernate之后,我们以操作Java实体的方式最终将数据改变映射到数据库表中. 为了解决抽象各个Java实体基本的"增删改查"操作,我们通常会以泛型的方式封装一个模板Dao来进行抽象简化,但是这

Spring boot实现数据库读写分离的方法

背景 数据库配置主从之后,如何在代码层面实现读写分离? 用户自定义设置数据库路由 Spring boot提供了AbstractRoutingDataSource根据用户定义的规则选择当前的数据库,这样我们可以在执行查询之前,设置读取从库,在执行完成后,恢复到主库. 实现可动态路由的数据源,在每次数据库查询操作前执行 ReadWriteSplitRoutingDataSource.java import org.springframework.jdbc.datasource.lookup.Abst

Spring Boot Mysql 数据库操作示例

本文默认你的开发环境.数据库已经安装好 想用使用数据库.我们需要现在pom文件中添加相应的依赖 pom.xml <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:sc

Java基于jdbc连接mysql数据库操作示例

本文实例讲述了Java基于jdbc连接mysql数据库操作.分享给大家供大家参考,具体如下: import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; public class MySQLDemo { private Connection conn = null; pri

基于ThinkPHP5框架使用QueryList爬取并存入mysql数据库操作示例

本文实例讲述了基于ThinkPHP5框架使用QueryList爬取并存入mysql数据库操作.分享给大家供大家参考,具体如下: QueryList4教程 地址: https://doc.querylist.cc/site/index/doc/45 在ThinkPHP5代码根目录执行composer命令安装QueryList: composer require jaeger/querylist 如果出现 以下错误 Loading composer repositories with package

Python3实现的爬虫爬取数据并存入mysql数据库操作示例

本文实例讲述了Python3实现的爬虫爬取数据并存入mysql数据库操作.分享给大家供大家参考,具体如下: 爬一个电脑客户端的订单.罗总推荐,抓包工具用的是HttpAnalyzerStdV7,与chrome自带的F12类似.客户端有接单大厅,罗列所有订单的简要信息.当单子被接了,就不存在了.我要做的是新出订单就爬取记录到我的数据库zyc里. 设置每10s爬一次. 抓包工具页面如图: 首先是爬虫,先找到数据存储的页面,再用正则爬出. # -*- coding:utf-8 -*- import re

Yaf框架封装的MySQL数据库操作示例

本文实例讲述了Yaf框架封装的MySQL数据库操作.分享给大家供大家参考,具体如下: Yaf封装DB简单操作 介绍 因为Yaf是一个纯天然的MVC阔架,本人还在贝锐的时候就和主管一起用Yaf框架去重构了向日葵的网站端,到后面,Yaf也逐渐应用到了其他项目上,但是Yaf是没有带DB类库的,所以本人也共享下最近封装的代码! 代码 使用PDO封装MySQL操作 class Db_Mysql { private $_options = array(); private $db; private $sta

spring boot读取Excel操作示例

本文实例讲述了spring boot读取Excel操作.分享给大家供大家参考,具体如下: 首先引入相关依赖 <!--解析office相关文件--> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>3.17</version> </dependency> <dependenc

Python操作MySQL数据库的示例代码

1. MySQL Connector 1.1 创建连接 import mysql.connector config={ "host":"localhost","port":"3306", "user":"root","password":"password", "database":"demo" } con=

PHP封装mysqli基于面向对象的mysql数据库操作类与用法示例

本文实例讲述了PHP封装mysqli基于面向对象的mysql数据库操作与用法.分享给大家供大家参考,具体如下: 首先封装好mysql类 mysql.php <?php class Mysql{ private static $host="localhost"; private static $user="root"; private static $password="123456"; private static $dbName=&quo

PHP实现PDO的mysql数据库操作类

本文实例讲述了PHP实现PDO的mysql数据库操作类.分享给大家供大家参考.具体分析如下: dbconfig类负责配置数据库访问信息,包括:服务器地址.端口.数据库实例名.用户名.用户密码.字符集等. dbtemplate类集合了对数据库的访问操作,主要有以下几个操作: 1. queryrows:返回多行记录 2. queryrow:返回为单条记录 3. queryforint:查询单字段,返回整数 4. queryforfloat:查询单字段,返回浮点数(float) 5. queryfor

jsp+mysql数据库操作常用方法实例总结

本文实例讲述了jsp+mysql数据库操作常用方法.分享给大家供大家参考.具体如下: 1. 查看: <%@ page contentType="text/html;charset=GB2312" %> <%@ page import="java.sql.*" %> <HTML><style type="text/css"> <!-- body { background-color: #99CC