SpringBoot使用flyway初始化数据库
概述
Flyway这款数据库版本工具就算大家没有使用过但也略有耳闻了,SpringBoot对该款工具进行集成的框架可以让我们在启动SpringBoot应用时自动去找SQL版本文件进行比对执行,但在迁移或初始化时往往还是需要先手动进行下数据库的初始化配置,否则会把Unknowndatabase的异常。为了减少这一步所以个人就以SpringBoot的方式编码在项目的启动时自动进行数据库的初始化,然后再执行版本文件。
自动建库实现步骤
具体思路
- SpringBoot的配置项都会有相应的Properties属性类,数据库的属性类为DataSourceProperties,flyway的属性类为FlywayProperties,尽可能的使用其中的配置项而不额外添加自定义的配置
- 建库与相关设置的语句一般不会对已存在的设置进行更改(如建库建表时都是CREATExxxIFNOTEXISTS),所以项目初始化时每次都执行也不会影响现有的数据库配置,编码时可以不用添加执行的前置判断
代码实现
配置文件
spring: profiles: include:database
application-database.yml
spring: datasource: url:jdbc:mysql://yourIp:3306/spring_boot_series?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true&serverTimezone=GMT username:yourUsername password:yourPassword driver-class-name:com.mysql.cj.jdbc.Driver #自动读取spring.datasource配置进行迁移操作 flyway: #版本迁移位置 locations:classpath:db baseline-version:1.0.2 init-sqls: -SET@OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS,UNIQUE_CHECKS=0; -SET@OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS,FOREIGN_KEY_CHECKS=0; -SET@OLD_SQL_MODE=@@SQL_MODE,SQL_MODE= 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION'; -CREATESCHEMAIFNOTEXISTS`spring_boot_series`DEFAULTCHARACTERSETutf8COLLATEutf8_general_ci;
为了让项目的配置结构更清晰,所以我把数据库的相关配置都独立到application-database.yml中。
flyway的init-sqls配置是当获取到SQLstatement时会执行SQL语句列表,但需要注意的是如果spring.datasource.url连接不上,该块语句是依旧无法被执行的,因为SpringBoot集成的flyway配置是通过spring.datasource的配置去连接数据库的,如果url中的数据库不存在,flyway的版本迁移就无法执行了。
前文提到尽可能的使用SpringBoot原有的配置项,所以init-sqls其实是我配给自己用的。个人通过init-sqls配置初始化语句与其它方式配置初始化想到的好处:
- 无需将初始化语句硬编码再让Statement执行
- 当数据库选型进行变更时只需再配置文件中进行修改相应的初始化语句
- SpringBoot可以直接以字符串列表进行读取,开发过程中使用起来更加灵活,而不用去解析SQL文件
数据库初始化器DatabaseInitializer
packageio.wilson.flyway; importcom.zaxxer.hikari.HikariDataSource; importlombok.AllArgsConstructor; importlombok.extern.slf4j.Slf4j; importorg.springframework.boot.autoconfigure.flyway.FlywayProperties; importorg.springframework.boot.autoconfigure.jdbc.DataSourceProperties; importorg.springframework.stereotype.Component; importjavax.annotation.PostConstruct; importjava.sql.Connection; importjava.sql.SQLException; importjava.sql.Statement; /** *@authorWilson */ @Slf4j @Component @AllArgsConstructor publicclassDatabaseInitializer{ privatefinalFlywayPropertiesflywayProperties; privatefinalDataSourcePropertiesdataSourceProperties; @PostConstruct publicvoidinit()throwsSQLException{ log.info("DatabaseInitializerusesflywayinit-sqlstoinitiatedatabase"); Stringurl=dataSourceProperties.getUrl(); //jdbcurl最后一个'/'用于分割具体schema?参数 intlastSplitIndex=url.lastIndexOf('/'); //获取spring.datasource.url具体数据库schema前的jdbcurl StringaddressUrl=url.substring(0,lastSplitIndex); //直连数据库地址:jdbc:mysql://yourIp:port HikariDataSourcedataSource=newHikariDataSource(); dataSource.setJdbcUrl(addressUrl); dataSource.setUsername(dataSourceProperties.getUsername()); dataSource.setPassword(dataSourceProperties.getPassword()); Connectionconnection=dataSource.getConnection(); Statementstatement=connection.createStatement(); for(Stringsql:flywayProperties.getInitSqls()){ //通过flyway的init-sqls配置进行建库与数据库配置 //executeUpdate:执行给定的SQL语句,该语句可以是INSERT,UPDATE或DELETE语句或不返回任何内容的SQL语句,例如SQLDDL语句。 statement.executeUpdate(sql); } statement.close(); connection.close(); dataSource.close(); log.info("DatabaseInitializerinitializecompleted"); } }
简单的主程序FlywayApplication
packageio.wilson.flyway; importorg.mybatis.spring.annotation.MapperScan; importorg.springframework.boot.SpringApplication; importorg.springframework.boot.autoconfigure.SpringBootApplication; /** *@authorWilson */ @SpringBootApplication @MapperScan("io.wilson.flyway.mapper") publicclassFlywayApplication{ publicstaticvoidmain(String[]args){ SpringApplication.run(FlywayApplication.class,args); } }
执行效果图
当项目启动时可以看到DatabaseInitializer会先通过init-sqls进行数据库的初始化,然后SpringBoot再初始化通用的数据源并执行SQL版本文件。图中的create_database.sql文件存放的是init-sqls配置的语句,该文件不会被执行,可以忽略。
附
- 如果对flyway不了解的可以看我之前的文章SpringBoot集成Flyway进行数据库版本迁移管理
- 本文例子仓库:spring-bootflyway-demo
- flyway官网文档
以上就是SpringBoot使用flyway初始化数据库的详细内容,更多关于SpringBoot初始化数据库的资料请关注毛票票其它相关文章!
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。