公有云部署项目之外,如果需要频繁的对项目进行本地化部署,每次都手动创建数据库和表,会很影响项目部署时间,对于不熟悉项目的技术人员部署更是难上加难,引入Flyway 这个数据库版本管理工具,可以支持数据库版本自动升级,Migrations可以写成sql脚本,也可以写在java代码里;不仅支持Command Line和java api ,也支持Build构建工具和Spring boot,也可以在分布式环境下能够安全可靠安全地升级数据库,同时也支持失败恢复。而且在后续开发项目的时候经常会更新数据库表的字段,如果同事 a 添加了表字段,没有及时给同事 b sql 脚本,可能同事 b 的代码运行就会报错,而且随着时间的推移,sql 脚本越来越多,项目上线的时候整理起来就很费时间。
1.需要引入的依赖:
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.1</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-core</artifactId>
<version>5.2.1</version>
</dependency>
2.修改application.yml:
spring为flyway准备了专属的数据源配置,但是在默认的情况下,可以直接使用spring.datasource的配置。
spring:
datasource:
driver-class-name: org.postgresql.Driver
url: jdbc:postgresql://${postgres.ip}:${postgres.port}/${postgres.database}?${postgres.param}
username: postgres
password: postgres
flyway:
enabled: true # 开启
clean-disabled: false # 禁止清理数据表
table: flyway_schema_history # 版本控制信息表名,默认 flyway_schema_history
out-of-order: false # 是否允许不按顺序迁移
baseline-on-migrate: true # 如果数据库不是空表,需要设置成 true,否则启动报错
baseline-version: 0 # 与 baseline-on-migrate: true 搭配使用,小于此版本的不执行
locations: classpath:db/migration #默认sql脚本路径为classpath:db/migration
baseline:
如果用户从一个已有的数据库导出脚本(脚本文件名中的版本号必须是V1),作为flyway的升级脚本。已存在的数据库是不需要升级的。
baseline用于将当前数据库标记为baseline,并记录version为1。这表示用户继续执行migrate命令时,会自动跳过V1版本对应的脚本。
而对于空的数据库,因为没有执行baseline,所以可以正常的执行V1版本对应的脚本。 手动修改flyway自动生成的baseline记录,将版本号改为其他的版本号,将自动跳过该版本及更早的版本。
3.在指定的目录编写脚本:
如果用户没有特地设置脚本的位置,则应该在/db/migration创建脚本。否则,在对应的位置创建脚本。
启动springboot项目,加载sql脚本,会发现数据库中新建了表数据
当SpringBoot启动时,文件会自动被使用。以V开头的文件会只会生效第一次,而以R开头的文件每次启动SpringBoot都会使用一次。
当成功后可以看到数据库中有一个自动生成的名叫 flyway_schema_history的表,flyway就是用flyway_schema_history这张表来记录执行信息的,当一份以V开头的文件被执行完之后会被记录到表中,而以R开头的文件因为每次启动都会执行一次,所有不会有记录到该表中。
当V开头的文件被执行后,其被记录到表中,一般来说,除非是删除flyway_schema_history,不然是无法再次执行该V文件的,如果在后来的情况中修改了V文件导致其信息和表记录的信息不符,还会在SpringBoot启动时报错。单独的删除flyway_schema_history中的一列,似乎是无法正确使被执行的文件再次执行第二次的。
springboot启动可能的问题:
不要在初始化spring bean的时候立即加载数据库,否则在安装部署的时候,该加载操作会在flyway初始化数据库之前进行,导致数据库无表。
问题解决思路:
自然是控制flyway的执行顺序,让flyway执行在依赖查询数据库配置的服务之前。 问题是springboot集成flyway是自动配置的,也就是说我们要想控制flyway的配置顺序,就得自己重写flyway的配置。