当前位置 博文首页 > 小黄鸡的博客:五分钟带你玩转flyway(一)手把手教你数据库版本

    小黄鸡的博客:五分钟带你玩转flyway(一)手把手教你数据库版本

    作者:[db:作者] 时间:2021-08-15 19:31

    flyway为数据库控制插件,使所有的数据库脚本都在ide(idea,eclipse等)中控制,这样能做到版本有迹可循

    这里需要注意如果使用flyway 就要禁止在数据库管理软件中更改数据库表结构

    springboot整合flyway

    pom.xml

            <dependency>
                <groupId>org.flywaydb</groupId>
                <artifactId>flyway-core</artifactId>
                <version>6.4.4</version>
            </dependency>

    application.yml

    spring:
     flyway: # flyway 数据库 DDL 版本控制
        enabled: true # 正式环境才开启
        clean-disabled: true # 禁用数据库清理
        encoding: UTF-8
        locations: classpath:/db #脚本存放地址
        table: flyway_schema_history_systemportal #flyway记录表,记录了当前执行到了那个脚本
        baseline-version: 1 # 基线版本默认开始序号 默认为 1
        baseline-on-migrate: true #  针对非空数据库是否默认调用基线版本,为空的话默认会调用基线版本
        placeholder-replacement: false
        placeholders: # 定义 afterMigrateError.sql 要清理的元数据表表名
          flyway-table: ${spring.flyway.table}

    在第一次初始化时有可能出现以下错误? 需要加上?placeholder-replacement: false

    脚本结构

    在定义初始化脚本时 版本号建议为V+(编号)+__(为双下划线)+业务名称+init? 例如楼主的?V1__systemportal_init.sql

    在定义变更版本时 版本号为?V+(编号)+__(为双下划线)+操作+表名称? 例如楼主的为V2__update_table.sql

    其中V1__systemportal_init.sql(初始化脚本)为项目所有的表结构与数据 以下方式导出

    V2__update_table.sql为变更版本(表结构变化的脚本,如果没有变更,只存在init脚本即可)其中内容如下?

    ALTER TABLE "systemportal"."task_plan"
      ALTER COLUMN "update_user" TYPE varchar(255) USING "update_user"::varchar(255);

    执行以上操作后 将原数据库表数据全部删除(记得做好备份) 然后启动项目 即可在数据库中生成表 说白了 就是按照db中的脚本依次执行一遍

    原理

    当使用flyway时 会生成一个记录表 记录当前已经执行的脚本名称(script字段就是已经执行了的db中的脚本)

    根据上文 在初始化时会产生以下记录

    如果再次启动时 会查询该表是否有大于V2版本的脚本 如果有执行这些脚本?如果没有什么也不执行

    整合quartz

    当整合quartz时 需要查询表 但是因为使用了flyway此时并没有表结构 所以需要处理

    1.注释掉@PostConstruct中内容(在服务启动时运行)

    ?2.添加以下配置(在启动后执行)

    @Component
    public class RuntimeConfig implements ApplicationListener<ContextRefreshedEvent> {
    
        @Autowired
        private Scheduler scheduler;
    
        @Autowired
        private QrtzJobDao qrtzJobDao;
    
        @Override
        public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) {
            this.initJob();
        }
    
        public void initJob() {
            QrtzJobVO qrtzJobVO = new QrtzJobVO();
            List<QrtzJobVO> scheduleJobList = qrtzJobDao.queryQrtzJobAll(qrtzJobVO);
            scheduleJobList.forEach(scheduleJob -> {
                CronTrigger cronTrigger = ScheduleUtils.getCronTrigger(this.scheduler, scheduleJob.getJobId());
                if (cronTrigger == null) {
                    ScheduleUtils.createScheduleJob(this.scheduler, scheduleJob);
                } else {
                    ScheduleUtils.updateScheduleJob(this.scheduler, scheduleJob);
                }
            });
        }
    }
    

    ?

    cs