12.30
MyBatis-Plus 实现获取 MySQL 数据库 DDL
核心核心:MyBatis-Plus 无直接获取 DDL 的API,核心靠 MySQL 系统函数/表 + MyBatis 原生SQL查询,2种常用实现方案,精简可直接复用。
方案1:单表 DDL 查询(最常用)
利用 MySQL 自带 SHOW CREATE TABLE 语句,直接查询单表完整建表语句,适配所有 MySQL 版本。
- 核心 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+ 支持。
-
Mapper 方法
@Select("SELECT TABLE_NAME, CREATE_TABLE_SQL FROM information_schema.TABLES " +
"WHERE TABLE_SCHEMA = #{dbName} AND TABLE_NAME IN #{tableNames}")
ListbatchGetTableDdl(@Param("dbName") String dbName, @Param("tableNames") List tableNames); -
配套VO类(接收结果)
@Data
public class TableDdlVo {
private String TABLE_NAME; // 表名
private String CREATE_TABLE_SQL; // 建表DDL
}
关键注意事项(避坑) -
传参用 ${tableName} 而非 #{}:表名不能预编译,用$直接拼接,需自行校验表名防注入(仅内部调用无需担心)。
-
权限要求:连接数据库的账号需有 SELECT 权限,即可查询系统表和表结构。
-
适配 MP 版本:所有 MyBatis-Plus 版本通用(本质是 MyBatis 原生SQL),无需额外依赖。
-
含注释/索引:两种方案查询的 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 权限;导出大量表时注意连接池与内存占用。

浙公网安备 33010602011771号