源本科技 | 码上会

自动 DDL 维护

2026/04/02
1
0

引言

功能概述

MyBatis-Plus 3.5.3 + 版本推出原生轻量级 DDL 自动维护功能,无需集成第三方工具(Flyway/Liquibase),即可实现:

  • 数据库表结构初始化、版本升级、脚本自动执行

  • 自动记录 DDL 执行历史,幂等执行(重复启动不重复执行)

  • 支持分库分表场景下的 DDL 执行(原生适配 MP 分片机制)

  • 支持 SQL 脚本、存储过程、自定义 SQL 执行

  • 全参数化配置:事务、错误处理、日志、执行策略自定义

核心优势

对比 Flyway/Liquibase

特性

MyBatis-Plus 原生 DDL

Flyway/Liquibase

集成成本

零依赖(MP 内置)

需单独引入依赖

分库分表

原生支持

适配复杂,需二次开发

轻量化

极简配置,无侵入

重型工具,配置繁琐

执行控制

代码级动态控制

配置文件控制

适用场景

微服务 / 分库项目快速落地

大型企业复杂版本管理


核心原理

  1. 历史表自动创建 项目首次启动时,自动创建 ddl_history,记录所有执行过的 SQL 脚本信息,保证只执行 1 次

  2. 执行规则 扫描实现 IDdl 接口的类 → 读取 SQL 脚本列表 → 校验 ddl_history → 仅执行未执行过的脚本。

  3. 核心组件

    • IDdl:定义需要执行的 SQL 脚本列表

    • DdlApplicationRunner:SpringBoot 启动后自动执行 DDL 脚本

    • ddl_history:DDL 执行历史记录表

    • DdlScriptErrorHandler:脚本错误处理器


ddl_history

表结构(自动生成)

MP 自动创建的历史表,字段含义如下:

字段名

类型

说明

id

bigint

主键

script_file

varchar(255)

执行的脚本文件名 / 路径

execute_time

datetime

执行时间

success

tinyint

执行状态(1 = 成功,0 = 失败)

message

text

执行结果 / 异常信息


使用步骤

存放 SQL 脚本

在项目 resources/db/ 目录下创建 DDL 脚本

resources/
└── db/
    ├── schema.sql    # 表结构初始化
    ├── data.sql       # 基础数据
    └── procedure.sql  # 存储过程

实现 IDdl 接口

声明需要执行的脚本,Spring 会自动扫描该组件:

import com.baomidou.mybatisplus.extension.ddl.IDdl;
import org.springframework.stereotype.Component;
import java.util.Arrays;
import java.util.List;

@Component
public class MyDdlScript implements IDdl {

    /**
     * 返回要执行的 SQL 脚本列表
     * 支持:classpath 相对路径、绝对路径
     * 执行顺序:按照列表顺序依次执行
     */
    @Override
    public List<String> getSqlFiles() {
        return Arrays.asList(
                "db/schema.sql",    // 表结构
                "db/data.sql",      // 基础数据
                // 存储过程:文件名后 + #自定义分隔符
                "db/procedure.sql#$$"
        );
    }
}

启动项目

  • 自动执行:无需任何额外配置,项目启动后自动执行脚本

  • 幂等性:重启项目不会重复执行已成功的脚本


DdlApplicationRunner

MP starter 会自动注册 DdlApplicationRunner,生产环境可自定义事务、错误处理、日志

import com.baomidou.mybatisplus.extension.ddl.DdlApplicationRunner;
import com.baomidou.mybatisplus.extension.ddl.IDdl;
import com.baomidou.mybatisplus.extension.ddl.handle.DdlScriptErrorHandler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.List;

@Configuration
public class DdlConfig {

    @Bean
    public DdlApplicationRunner ddlApplicationRunner(List<IDdl> ddlList) {
        DdlApplicationRunner runner = new DdlApplicationRunner(ddlList);

        // 1. 事务配置
        runner.setAutoCommit(false);        // 关闭自动提交(手动事务,失败回滚)
        runner.setThrowException(true);     // 遇到异常直接终止项目启动

        // 2. 错误处理:抛出异常终止执行(默认:忽略错误)
        runner.setDdlScriptErrorHandler(DdlScriptErrorHandler.ThrowsErrorHandler.INSTANCE);

        // 3. 脚本执行细节配置
        runner.setScriptRunnerConsumer(scriptRunner -> {
            scriptRunner.setStopOnError(true);    // 单脚本遇到错误立即停止
            scriptRunner.setLogWriter(null);      // 关闭执行日志
            scriptRunner.setErrorLogWriter(null); // 关闭错误日志
        });

        return runner;
    }
}

配置说明

参数

作用

默认值

autoCommit

事务自动提交

true

throwException

异常是否中断启动

false

stopOnError

单脚本错误是否终止

false

logWriter

执行日志输出

System.out


错误处理器

MP 提供两种标准错误处理策略:

  1. ThrowsErrorHandler:抛出异常,终止项目启动(生产环境推荐

  2. IgnoreErrorHandler:忽略错误,打印日志,继续执行(默认)


执行规则

  1. 脚本执行顺序:严格按照 getSqlFiles() 列表顺序执行

  2. 重复执行:仅执行 ddl_history 中无记录的脚本

  3. 失败处理:默认忽略错误;开启 stopOnError 后,失败终止

  4. 路径支持

    • 相对路径:db/schema.sql(resources 目录下)

    • 绝对路径:D:/db/schema.sql(Windows)、/opt/db/schema.sql(Linux)