一、背景
- 不知道你是否有过被数据库虐过,初始化时报错某个表的表字段不存在,某个表不存在,然后我们拿着不完整的文档,捣鼓来捣鼓去,好的,大半天时间搞定;文档写的差的,搞得心态爆炸,然后还要到处问有没有最新文档啥的。
- 同事对数据库做了改动并且代码合并到线上(我并不参与review),之后我拉取线上代码,连接本地数据库启动项目,报错,原因是本地没有新添加的数据表,而项目启动依赖于他。
- 完成一个需求之后,打算将代码上线,需要在代码合入之前手动去线上(去服务器上或者通过phpmyadmin等工具)执行sql创建数据表。
二、为啥要使用flyway?
- 在日常的开发中,我们使用git管理代码的迭代,那么数据库怎么进行版本迭代呢?当然时使用flyway。 个人认为,可以大概的将flyway理解为数据库的git,方便多人协作、记录和自动同步数据库的迭代。git让你和同事更加轻松的维护同一个项目,你可以很方便的获取到他最新提交的改动。flyway让你及时的知道同事对数据库的改动并且能够自动在你的本地执行这些改动,可以完美解决上述的三个常见问题。
- 和同事同时维护一个项目,同时对数据库做出了一些修改,我在使用git拉取了最新的代码之后,运行总是报错,需要自己去重新执行一遍该表的创建语句来在本地进行创建,使用flyway后,拉取最新代码的同时会拉取最新的sql文件,同时在服务启动时自动创建数据表,对一些和自己无关的数据表完全不用关心了。
- 新接手一个项目,在本地进行开发调试,本地新建数据库后,需要执行一遍建表语句,使用flyway可以自动的创建该项目的所有表格。
- 换电脑,我日常开发使用一台台式机及一台笔记本,紧急情况使用家中笔记本进行一些开发,在每次新换电脑时都需要重新创建一遍数据库的表,十分的麻烦。使用flyway的遍历同第二点(可以理解为换电脑等于在新电脑上运行新项目)。
三、怎么使用flyway?
- 添加依赖
<dependency> <groupId>org.flywaydb</groupId> <artifactId>flyway-core</artifactId> </dependency>
- 在application.yml中添加配置
spring: flyway: url: jdbc:mysql://127.0.0.1:3306/db schemas: db user: root password: 123456
- 在resources目录下添加db.migration目录,下添加.sql文件,命名格式如下:
四、flyway执行机制
1. flyway是依靠什么判断版本呢?
使用过一次之后你就知道,是根据数据库中schemas_version表的记录。你每次执行过一次sql文件,在该表中就会添加一条类似于V13 success
的数据。当项目启动时,flyway扫描sql文件,发现当前有V14开头的文件,同时数据库中没有V14执行的记录,那么就会执行该文件。
2. 怎么在已有的项目添加flyway依赖呢?
你可以将当前数据库的所有表格创建语句导出到sql文件,然后新建V1__init_database.sql文件,将所有创建语句copy到该文件中,然后创建新库,连接新库启动项目,之后copy新库中schemas_version数据表的结构及数据,添加到已有的数据库中,这样项目启动时便不会对已有的数据库产生影响。这波操作的本质是:模仿一条记录,让flyway认为当前的数据库是一个已经执行过的版本,不做任何的改动,后续的改动继续添加即可。有时会写入错误的sql语句,修改后再次执行便会报错显示数据库中已有该版本的记录,此时进入数据库删除schemas_version中对应记录重新执行即可。(反正在开发环境无所谓的,我们又不会去生产环境执行错误的sql)。