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中的所有表均已创建


    谢幕

posted @ 2021-07-26 17:28  -至尊宝-  阅读(401)  评论(0编辑  收藏  举报