
本文详解如何通过 java jdbc 调用 hsqldb 内置 sql 命令,精准备份和恢复指定表(含 ddl 结构与完整数据),避免全库导出,满足精细化数据迁移与测试场景需求。
本文详解如何通过 java jdbc 调用 hsqldb 内置 sql 命令,精准备份和恢复指定表(含 ddl 结构与完整数据),避免全库导出,满足精细化数据迁移与测试场景需求。
HSQLDB 自 2.0 版本起提供了强大的脚本化数据管理命令,其中 PERFORM EXPORT SCRIPT FOR TABLE 和 PERFORM IMPORT SCRIPT DATA 是实现单表级结构+数据一体化备份/恢复的核心机制。与全库 .tar.gz 备份不同,该方案支持按需选择表名、生成可读 SQL 文件(含 CREATE TABLE 和 INSERT 语句),并完全兼容 JDBC 标准调用,无需外部工具或文件系统级操作。
✅ 正确的备份与恢复流程
1. 备份指定表(含结构 + 数据)
使用 PERFORM EXPORT SCRIPT FOR TABLE table_name DATA 命令,将目标表的 DDL 定义与全部行数据导出为标准 SQL 脚本。注意:
- DATA 关键字必须显式指定,否则仅导出表结构(无 INSERT);
- 导出路径为数据库所在目录的相对路径(如 ./backup/users.sql),且需确保 HSQLDB 进程对该路径有写权限;
- 支持一次执行一条表,多表需循环调用。
String[] tablesToBackup = {"USERS", "ORDERS", "PRODUCTS"}; // 大写(HSQLDB 默认大写标识符)
String backupDir = "./backup/";
try (Connection conn = DriverManager.getConnection("jdbc:hsqldb:hsql://localhost/testdb", "SA", "")) {
try (Statement stmt = conn.createStatement()) {
for (String tableName : tablesToBackup) {
String scriptPath = backupDir + tableName.toLowerCase() + ".sql";
String exportSql = String.format(
"PERFORM EXPORT SCRIPT FOR TABLE %s DATA TO '%s'",
tableName, scriptPath
);
stmt.execute(exportSql);
System.out.println("✅ Exported: " + tableName + " → " + scriptPath);
}
}
} catch (SQLException e) {
throw new RuntimeException("Backup failed", e);
}⚠️ 注意事项:
- 表名需严格匹配数据库中实际名称(默认大写,若建表时用双引号定义小写名,则导出时也需加双引号,如 "users");
- 导出路径不支持绝对路径(如 /tmp/xxx.sql),否则抛出 SQLSyntaxErrorException;
- 若目标目录不存在,HSQLDB 不会自动创建,需提前确保 ./backup/ 目录存在。
2. 恢复指定表(重建结构 + 插入数据)
使用 PERFORM IMPORT SCRIPT DATA FROM 'path/to/file.sql' 执行已导出的 SQL 脚本。该命令会自动解析并顺序执行其中的 CREATE TABLE(若表不存在)和 INSERT 语句。
立即学习“Java免费学习笔记(深入)”;
String[] scriptsToImport = {"./backup/users.sql", "./backup/orders.sql"};
try (Connection conn = DriverManager.getConnection("jdbc:hsqldb:hsql://localhost/testdb", "SA", "")) {
try (Statement stmt = conn.createStatement()) {
for (String scriptPath : scriptsToImport) {
String importSql = String.format("PERFORM IMPORT SCRIPT DATA FROM '%s'", scriptPath);
stmt.execute(importSql);
System.out.println("✅ Imported: " + scriptPath);
}
}
} catch (SQLException e) {
throw new RuntimeException("Import failed", e);
}⚠️ 注意事项:
- IMPORT SCRIPT DATA 不会自动 DROP 或 TRUNCATE 原表。若目标表已存在且结构不兼容,可能因主键冲突、列类型不匹配等导致导入失败;建议在导入前手动清理(如 DROP TABLE IF EXISTS USERS);
- 导入脚本中的 CREATE TABLE 语句若遇到同名表,将直接报错(HSQLDB 不支持 CREATE TABLE IF NOT EXISTS 在此上下文中),因此生产环境推荐先校验表状态;
- 所有操作均在当前连接事务中执行,但 PERFORM 命令本身不支持回滚——一旦部分导入失败,已执行的 INSERT 不可逆,需谨慎设计幂等逻辑。
? 补充说明与最佳实践
- 替代方案对比:SCRIPT TO 'file.sql' 命令导出的是整个数据库的 DDL + 数据,无法按表过滤;而 PERFORM EXPORT SCRIPT FOR DATABASE 仅生成结构(无数据)。二者均不满足本场景“指定表+含数据”要求。
- 性能提示:对大表(百万级行),导出/导入耗时较长,建议在低峰期执行,并考虑启用 HSQLDB 的 SET FILES WRITE DELAY 0 提升 I/O 效率(测试环境可用,生产慎用)。
- 可扩展性建议:可封装为工具类,支持通配符(如 USER%)、排除系统表(INFORMATION_SCHEMA.*)、自动生成导入依赖顺序(基于外键关系分析),进一步提升工程化能力。
通过上述 JDBC 驱动的原生命令调用,开发者可在 Java 应用中完全掌控 HSQLDB 的细粒度数据生命周期管理,兼顾简洁性、可维护性与生产可靠性。










