Java敏捷数据库迁移框架——Flyway
1.引言
想到要管理数据库的版本,是在实际产品中遇到问题后想到的一种解决方案,当时各个环境的数据库乱作一团,没有任何一个人(开发、测试、维护人员)能够讲清楚当前环境下的数据库是哪个版本,与哪个版本的应用相匹配,如何升级到与新版本的应用相匹配。
想到管理数据库版本时,先是心底形成了一个初步的解决方案,大致是通过数据库中的某张表来记录数据库表结构的历次更新与对应版本,在每次数据库表结构调整时除了提供库表更新sql ,还必须提供更新记录与对应版本的sql,以帮助维护数据库版本信息,并在遇到问题时提供相关的排查依据。
后来据此思路在网络上搜索了一把,结果搜到Liquibase (另一款开源数据库版本管理工具)。在学习了解Liquibase 的时候,经高手介绍又了解到了Flyway 这个项目的存在。经过一番了解,最后我们选择了Flyway ,主要原因是Flyway 支持sql 脚本,而Liquibase 只支持XML 方式的数据库表结构定义,虽然在新的版本中号称在XML的数据库表结构定义方式中支持了sql 脚本。
虽然Flyway 的中文文档近乎为零,英文文档也凤毛麟角,但它却是我们最理想的数据库版本管理工具,它不但支持sql 脚本,还支持Java 代码直接操作数据库(在版本升级时做数据迁移相当有用),有Maven 插件,支持命令行(我们的平台数据库有部分由C 语言项目管理),而且在Spring 框架的配合下,很容易就能实现应用启动时自动检查并升级数据库的功能。
2.什么是flyway
Flyway 是独立于数据库的应用、管理并跟踪数据库变更的数据库版本管理工具。
Flyway 的项目主页是 http://flywaydb.org/)(最近才迁移到这个主页,之前一直在googlecode 下管理http://code.google.com/p/flyway/),在项目的主页上可以看到Flyway 与几款主流数据库版本管理工具的特性对比列表。
3.为什么使用flyway
我们遇到的问题(以下内容来自Flyway 的一些英文文档,从中抽取出来的我们也遇到的一些主要问题):
- 不同的开发人员在开发产品特性时,都有可能更新数据库(添加新表,新的约束等)。当开发人员完成工作并提交代码时,代码会被合并到主分支并在测试服务器上执行单元测试与集成测试。我们在哪个环节来执行数据库的更新操作呢?由QA 部门手工执行sql 脚本?或者我们开发一断程序自动执行数据库更新?以什么顺序来执行这些更新脚本?这些问题同样存在于生产环境。
- 我们的产品部署在不同的客户服务器上,以及很多的测试、联调、实验局、销售环境上。不同的客户和测试环境上都部署着不同版本的产品。当他们需要升级他们的产品到新的版本时,我们不仅需要让他们的管理员可以升级产品到新的版本,同时需要保留他们的已有数据。在升级产品的步骤中,我们清楚地知道客户数据库的当前版本,以及需要在该数据库上执行哪些数据库更新脚本,来更新数据库表结构与数据库中已存在的数据。当升级完成时,数据库表结构及数据应当与升级后的产品版本保持一致。
- 有的时候,我们需要通过代码(Java )来维护一些已存在的数据,如通过代码来维护blob 类型的用户头像数据。
- 当升级失败时(比如在升级过程中出现网络连接失败),我们应当支持对失败进行修复。
4.如何使用flyway
Flyway 的主要任务是管理数据库的版本更新,在Flyway 中称每次数据库更新为一个migration ,为了更顺口,我们下面称之为数据库脚本。Flyway 支持SQL-based migrations 和Java-based migrations 。
Flyway 支持的数据库脚本有sql 脚本与java 代码,sql 脚本即普通的sql 脚本,包含创建数据库、表,更新库表结构,数据插入、更新、删除等sql 语句,java 代码则是通过一个有效的数据源,使用java 语言来进行数据库的操作,这里针对的读者是对数据库操作有一定熟悉程度的群体,不再详细讲解如何编写数据库脚本。
- SQL 脚本文件默认位置是项目的源文件夹下的db/migration 目录。
- Java 代码默认位于db.migration 包。
- SQL 脚本文件及Java 代码类名必须遵循以下命名规则:V<version>[_<SEQ>][__description] 。版本号的数字间以小数点(. )或下划线(_ )分隔开,版本号与描述间以连续的两个下划线(__ )分隔开。如V1_1_0__Update.sql 。Java 类名规约不允许存在小数点,所以Java 类名中版本号的数字间只能以下划线进行分隔。
- 创建maven环境
![]()
- 增加flyway依赖
- <dependency>
- <groupId>com.googlecode.flyway</groupId>
- <artifactId>flyway-core</artifactId>
- <version>2.3</version>
- </dependency>
- <dependency>
- <groupId>mysql</groupId>
- <artifactId>mysql-connector-java</artifactId>
- <version>5.1.6</version>
- </dependency>
- 整合flyway
- Flyway flyway = new Flyway();
- flyway.setInitOnMigrate(true);//Whether to automatically call init when migrate is executed against a non-empty schema with no metadata table.
- flyway.setInitVersion("0");//设置初始化版本
- flyway.setDataSource(dataSource);
- flyway.setTable(databaseMigrateInfo.getTable());//设置存放flyway metadata数据的表名
- flyway.setLocations(new String[] { databaseMigrateInfo
- .getLocation() });//设置flyway扫描sql升级脚本、java升级脚本的目录路径或包路径
- flyway.migrate();
注意:1.会生成版本管理表;
2.版本号可以从0开始,可以设置初始化版本;
Java敏捷数据库迁移框架——Flyway的更多相关文章
- 数据库迁移框架Flyway介绍
官方文档 https://flywaydb.org/getstarted/firststeps/api[https://flywaydb.org/getstarted/firststeps/api] ...
- 195. Spring Boot 2.0数据库迁移:Flyway
[视频&交流平台] àSpringBoot视频:http://t.cn/R3QepWG à SpringCloud视频:http://t.cn/R3QeRZc à Spring Boot源码: ...
- 数据库迁移神器——Flyway
不知道你有没有遇到过这种场景,一套代码部署在不同的环境中,随着时间的过去,各个环境代码有版本差异,代码层面可以通过不同的版本来控制,但是数据库层面经常容易忘记更新! 前言 比如刚开始环境 A 和环境 ...
- 阿里P7整理“硬核”面试文档:Java基础+数据库+算法+框架技术等
现在的程序员越来越多,大部分的程序员都想着自己能够进入大厂工作,但每个人的能力都是有差距的,所以并不是人人都能跨进BATJ.即使如此,但身在职场的我们一刻也不能懈怠,既然对BATJ好奇,那么就要朝这个 ...
- 细说flask数据库迁移
什么情况下要用数据库迁移? 在开发过程中,需要修改数据库模型,而且还要在修改之后更新数据库.最直接的方式就是删除旧表,但这样会丢失数据. 更好的解决办法是使用数据库迁移框架,它可以追踪数据库模式的变化 ...
- 使用FluentMigrator进行数据库迁移
介绍 在开发的过程中,经常会遇到数据库结构变动(表新增.删除,表列新增.修改.删除等).开发环境.测试环境.正式环境都要记性同步:如果你使用EF有自动迁移的功能,还是挺方便的.如果非EF我们需要手工处 ...
- Flask从入门到精通之使用Flask-Migrate实现数据库迁移
在开发程序的过程中,你会发现有时需要修改数据库模型,而且修改之后还需要更新数据库.仅当数据库表不存在时,Flask-SQLAlchemy 才会根据模型进行创建.因此,更新表的唯一方式就是先删除旧表,不 ...
- Flask 数据库迁移
在开发过程中,需要修改数据库模型,而且还要在修改之后更新数据库.最直接的方式就是删除旧表,但这样会丢失数据. 更好的解决办法是使用数据库迁移框架,它可以追踪数据库模式的变化,然后把变动应用到数据库中. ...
- Flask项目中数据库迁移的使用
数据库迁移 在开发过程中,需要修改数据库模型,而且还要在修改之后更新数据库.最直接的方式就是删除旧表,但这样会丢失数据. 更好的解决办法是使用数据库迁移框架,它可以追踪数据库模式的变化,然后把变动应用 ...
随机推荐
- JavaEE基础(二十四)/多线程
1.多线程(多线程的引入) 1.什么是线程 线程是程序执行的一条路径, 一个进程中可以包含多条线程 多线程并发执行可以提高程序的效率, 可以同时完成多项工作 2.多线程的应用场景 红蜘蛛同时共享屏幕给 ...
- JavaEE基础(十)
1.面向对象(package关键字的概述及作用) A:为什么要有包 将字节码(.class)进行分类存放 包其实就是文件夹 B:包的概述 举例: 学生:增加,删除,修改,查询 老师:增加,删除,修改, ...
- PHP 设计模式之观察者模式
现在有两派,有的人建议使用设计模式,有的人不建议使用设计模式!这就向写文章一样,有的人喜欢文章按照套路走,比如叙事性质的文章,时间,地点,人物,事件.而有的人喜欢写杂文或者散文,有的人喜欢写诗词! 现 ...
- word 排版问题
1.wps word为何设置了页边距后下面的页边距不变呢 在章节选项卡中,查看章节导航,有可能是文档分节了,光标所在的节已经调整,而你看到页是另一节 2.分栏 选中你要进行分栏的内容,进行分栏,也可以 ...
- Unity GUI内绘制贝塞尔曲线
用Handles可以直接在GUI下绘制贝塞尔 using UnityEditor; using UnityEngine; using System.Collections; public class ...
- JAVA基础知识之JVM-——动态代理(AOP)
代理模式简介 在很多场景下,我们想使用一个类(通常是接口)A时,并不是直接使用这个类,而是通过另外一个类B去调用A的方法,这里的类B就是一个代理类. 有很多场景都会用到这种方法,例如假如创建类A需要很 ...
- touch 命令
gcc 或 mmm等命令进行编译时,判断文件是否改变是根据文件的修改日期做判断的,但有些情况改变文件后,可能时间没有很快更新,导致编译不到,那么用 touch ./* 把对应目录下文件时间更新一下再编 ...
- 手把手教你修改iOS版QQ的运动步数
手把手教你修改iOS版QQ的运动步数 现在很多软件都加上了运动模块,比如QQ和微信,而且还有排行榜,可以和好友比较谁的运动步数多,任何东西只要添加了比较功能,就变得不一样了.今天教大家用代码去修改QQ ...
- await和async关键字来写异步程序
await和async关键字出现于.Net5.0,方便写异步程序. 例子: public class MyClass { public MyClass() { DisplayValue(); //这里 ...
- Linux下常用的shell命令记录1
硬件篇 CPU相关 lscpu #查看的是cpu的统计信息. cat /proc/cpuinfo #查看CPU信息详细信息,如每个CPU的型号,主频等 内存相关 free -m #概要查看内存情况 ...