liquibase集成spring
摘要:liquibase集成spring boot项目中网上有很多资料,但该spring boot项目在启动时就要使用数据库,此时liquibase还未创建数据表,如何破解?
我们知道如果我们要在一个类使用spring提供的bean对象,我们需要把这个类注入到spring容器中,交给spring容器进行管理。这里liquibase便是是bean。
spring boot还有一个注解@DependsOn,它可以控制各个bean的启动顺序。(关于@DependsOn自行查阅资料)
下面举例:
-
需求
nacos是alibaba开源的提供注册中心和配置中心的开源组件,它也是一个spring boot项目
现在需要将liquibase集成在nacos中,在启动nacos时利用liquibase初始化表
-
尝试
-
pom文件
-
添加依赖
<!--Liquibase--> <dependency> <groupId>org.liquibase</groupId> <artifactId>liquibase-core</artifactId> <!--<version>3.6.3</version>--> </dependency>
-
添加插件
<plugin> <groupId>org.liquibase</groupId> <artifactId>liquibase-maven-plugin</artifactId> <!--<version>3.0.5</version>--> <executions> <execution> <phase>process-resources</phase> </execution> </executions> </plugin>
-
-
配置 application.properties
spring.liquibase.enabled: true spring.liquibase.user: root spring.liquibase.password: 123456 spring.liquibase.url: jdbc:mysql://127.0.0.1:3306/test?allowMultiQueries=true&useUnicode=true&characterEncoding=utf-8&useOldAliasMetadataBehavior=true&useSSL=false&serverTimezone=UTC
-
resources\db\changelog\db.changelog-master.yaml
文件路径是固定的,不能写错
databaseChangeLog: - includeAll: path: db/changelog/mse/mysql/ relativeToChangelogFile: false
-
changelog file
changelog file是liquibase的核心文件,可以是xml sql json,推荐xml
change file放在db.changelog-master.yaml中指定的目录,该例是db/changelog/mse/mysql/,即
resources\db\changelog\mse\mysql\
includeAll的意思是执行该目录下的所有文件
对应的还有 includeFile,执行指定的单个文件
changelog书写规范自行查阅,在此不是重点内容
-
启动
配置结束,启动nacos
恭喜,报错!找不到config_info这张表,但这张表在changelog中已经配置了啊!
定位:发现数据库中所有的表都没有生成,经过Ten Thousand Years,定位到问题,nacos初始化数据库先于liquibase启动
-
-
解决问题
思路:既然nacos启动就要读表,name找到读表的方法,让liquibase在其之前执行
查阅资料:
- liquibase集成在spring boot中是以bea形式注册在容器中的
- 注解@Dependson可以指定bean启动顺序,
修改:
nacos启动连接数据库的方法在
mse-nacos\src\main\java\com\alibaba\nacos\config\server\service\repository\extrnal\ExternalStoragePersistServiceImpl.java
添加注解,被添加注解的方法或类执行前,注解中的bean会先执行。如下例中的"liquibase"将先执行,然后再执行ExternalStoragePersistServiceImpl
@Conditional(value = ConditionOnExternalStorage.class) @Component @DependsOn("liquibase") public class ExternalStoragePersistServiceImpl implements PersistService
理论上来说,liquibase先创建表,nacos再启动连接数据库读表,过程完美
再次启动:
没有报错
查看数据局库,changelog中的所有表均已创建
谢幕