12.30

MyBatis-Plus 实现获取 MySQL 数据库 DDL

核心核心:MyBatis-Plus 无直接获取 DDL 的API,核心靠 MySQL 系统函数/表 + MyBatis 原生SQL查询,2种常用实现方案,精简可直接复用。

方案1:单表 DDL 查询(最常用)

利用 MySQL 自带 SHOW CREATE TABLE 语句,直接查询单表完整建表语句,适配所有 MySQL 版本。

  1. 核心 Mapper 方法(无需实体类,返回 Map 接收结果)
    import com.baomidou.mybatisplus.core.mapper.BaseMapper;
    import org.apache.ibatis.annotations.Select;
    import java.util.Map;

public interface TableInfoMapper extends BaseMapper {
// 传参为表名(需传全表名,含schema可加前缀如test.user)
@Select("SHOW CREATE TABLE ${tableName}")
Map<String, String> getTableDdl(@Param("tableName") String tableName);
}
2. 调用与取值
// 注入mapper后直接调用,如查询user表
Map<String, String> result = tableInfoMapper.getTableDdl("user");
// 核心key固定为Create Table,对应值就是完整DDL
String ddl = result.get("Create Table");
System.out.println(ddl);
方案2:全库/批量表 DDL 查询

查询 information_schema.TABLES 系统表,批量获取多表DDL,适合批量导出场景,仅 MySQL 5.0+ 支持。

  1. Mapper 方法
    @Select("SELECT TABLE_NAME, CREATE_TABLE_SQL FROM information_schema.TABLES " +
    "WHERE TABLE_SCHEMA = #{dbName} AND TABLE_NAME IN #{tableNames}")
    List batchGetTableDdl(@Param("dbName") String dbName, @Param("tableNames") List tableNames);

  2. 配套VO类(接收结果)
    @Data
    public class TableDdlVo {
    private String TABLE_NAME; // 表名
    private String CREATE_TABLE_SQL; // 建表DDL
    }
    关键注意事项(避坑)

  3. 传参用 ${tableName} 而非 #{}:表名不能预编译,用$直接拼接,需自行校验表名防注入(仅内部调用无需担心)。

  4. 权限要求:连接数据库的账号需有 SELECT 权限,即可查询系统表和表结构。

  5. 适配 MP 版本:所有 MyBatis-Plus 版本通用(本质是 MyBatis 原生SQL),无需额外依赖。

  6. 含注释/索引:两种方案查询的 DDL 均包含表注释、字段注释、索引、主键等完整信息,与 navicat 导出一致。

拓展:工具类封装(一键调用)

封装成静态工具类,无需注入mapper,直接传入JDBC连接即可用,适配非MP场景
public static String getTableDdl(Connection conn, String tableName) throws SQLException {
String sql = "SHOW CREATE TABLE " + tableName;
try (PreparedStatement ps = conn.prepareStatement(sql);
ResultSet rs = ps.executeQuery()) {
if (rs.next()) {
return rs.getString("Create Table");
}
return null;
}
}
要不要我帮你把这个单表获取DDL的逻辑,封装成一个可直接复用的 通用工具类,适配多数据源场景?

MyBatis-Plus 获取 MySQL 数据库所有表的 DDL

一、核心思路

• 在 MySQL 中,单表 DDL 通过 SHOW CREATE TABLE 表名 获取;要批量获取,需要先查询 information_schema.TABLES 拿到所有表名,再遍历执行 SHOW CREATE TABLE。注意 SHOW CREATE TABLE 的结果列名为 Create Table,需要正确映射。若需要视图 DDL,可用 SHOW CREATE VIEW 视图名。也可使用 mysqldump --no-data 一键导出结构。

二、代码实现 MyBatis-Plus 方式

• 依赖与配置:使用 MyBatis-Plus 3.x,数据源配置指向目标库。

• Mapper

@Mapper
public interface MetaMapper {

// 1) 查当前库所有基表名
@Select("SELECT TABLE_NAME " +
        "FROM information_schema.TABLES " +
        "WHERE TABLE_SCHEMA = DATABASE() AND TABLE_TYPE = 'BASE TABLE' " +
        "ORDER BY TABLE_NAME")
List<String> listTableNames();

// 2) 查指定库所有基表名
@Select("SELECT TABLE_NAME " +
        "FROM information_schema.TABLES " +
        "WHERE TABLE_SCHEMA = #{schema} AND TABLE_TYPE = 'BASE TABLE' " +
        "ORDER BY TABLE_NAME")
List<String> listTableNamesBySchema(@Param("schema") String schema);

// 3) 获取单表 DDL(关键:结果列名为 Create Table)
@Select("SHOW CREATE TABLE ${tableName}")
@Results(@Result(property = "ddl", column = "Create Table"))
Map<String, String> showCreateTable(@Param("tableName") String tableName);

}

• Service

@Service
public class DdlService {
@Autowired
private MetaMapper metaMapper;

// 获取当前库所有表的 DDL:Map<表名, DDL>
public Map<String, String> getAllTableDdls() {
    List<String> tables = metaMapper.listTableNames();
    Map<String, String> ddls = new LinkedHashMap<>();
    for (String t : tables) {
        Map<String, String> row = metaMapper.showCreateTable(t);
        ddls.put(t, row.get("Create Table")); // 或 row.get("ddl")
    }
    return ddls;
}

// 指定库
public Map<String, String> getAllTableDdls(String schema) {
    List<String> tables = metaMapper.listTableNamesBySchema(schema);
    Map<String, String> ddls = new LinkedHashMap<>();
    for (String t : tables) {
        Map<String, String> row = metaMapper.showCreateTable(t);
        ddls.put(t, row.get("Create Table"));
    }
    return ddls;
}

}

• 说明

◦ 如需并发导出,可使用 parallelStream,但请控制并发度避免连接池耗尽。

◦ 如需同时导出视图,新增方法:@Select("SHOW CREATE VIEW ${viewName}") 并复用上面的映射方式。

三、命令行一键导出所有表 DDL(备选)

• 仅导出结构(不含数据)到文件:

mysqldump -u用户名 -p --no-data 数据库名 > db_structure.sql

• 如需包含视图、触发器、存储过程等对象,可添加相应参数或使用工具的导出结构功能。

四、常见注意事项

• 结果列名映射:SHOW CREATE TABLE 返回的 DDL 列名为 Create Table,需用 @Result(column = "Create Table") 或别名映射,否则拿不到值。

• 只取基表:筛选条件建议加上 TABLE_TYPE = 'BASE TABLE',避免把视图等对象带入。

• 指定库更稳妥:生产连接可能未默认选中库,SQL 中用 TABLE_SCHEMA = ? 明确目标库,避免串库。

• 权限要求:执行 SHOW CREATE TABLE 需要对目标表有 SELECT 权限;导出大量表时注意连接池与内存占用。

posted @ 2025-12-30 11:35  chaoshang8  阅读(2)  评论(0)    收藏  举报