
本文详解如何使用 java jdbc 调用 hsqldb 内置 sql 命令,精准备份与恢复指定表(含结构与数据),避免全库导出,支持灵活表名列表控制、事务安全及脚本可重入性。
本文详解如何使用 java jdbc 调用 hsqldb 内置 sql 命令,精准备份与恢复指定表(含结构与数据),避免全库导出,支持灵活表名列表控制、事务安全及脚本可重入性。
HSQLDB 提供了轻量、原生的 SQL 级数据管理命令,无需外部工具或文件系统操作,即可实现单表/多表级的结构+数据一体化导出与导入。核心依赖两条管理语句:
- PERFORM EXPORT SCRIPT FOR TABLE table_name DATA:导出指定表的完整 DDL(CREATE TABLE)和 INSERT 语句(含数据);
- PERFORM IMPORT SCRIPT DATA FROM 'path/to/export.sql':从 SQL 脚本文件批量执行建表与插入操作。
该方案完全基于 JDBC 执行,不依赖 .tar 全库备份,满足“50+ 表中仅备份 12 张”的精细化运维需求。
✅ 完整 Java 实现示例
以下代码封装了多表导出与安全导入逻辑,支持自定义表名列表、输出路径及错误回滚:
import java.io.*;
import java.sql.*;
public class HsqlTableBackupRestore {
private static final String JDBC_URL = "jdbc:hsqldb:file:mydb;shutdown=true";
private static final String USER = "SA";
private static final String PASSWORD = "";
// 【导出】将指定表结构与数据导出为 SQL 脚本
public static void exportTables(Connection conn, List<String> tableNames, File outputFile)
throws SQLException, IOException {
try (PrintWriter writer = new PrintWriter(new FileWriter(outputFile))) {
// 先写入头部注释与兼容性设置
writer.println("-- HSQLDB Table Export Script");
writer.println("-- Generated on: " + new java.util.Date());
writer.println("SET DATABASE REFERENTIAL INTEGRITY FALSE;");
for (String tableName : tableNames) {
String sql = "PERFORM EXPORT SCRIPT FOR TABLE " + tableName + " DATA";
try (Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(sql)) {
// EXPORT SCRIPT 返回单行单列(CLOB 类型),内容为完整 SQL 文本
if (rs.next()) {
String script = rs.getString(1);
if (script != null && !script.trim().isEmpty()) {
writer.print(script);
writer.println(";"); // 确保语句结尾分号
}
}
}
}
writer.println("SET DATABASE REFERENTIAL INTEGRITY TRUE;");
}
}
// 【导入】执行导出的 SQL 脚本(需确保目标库为空或已清理同名表)
public static void importScript(Connection conn, File scriptFile) throws SQLException, IOException {
String sql = Files.readString(scriptFile.toPath());
try (Statement stmt = conn.createStatement()) {
// HSQLDB 支持以分号分割的批处理(需启用 multi-statement)
stmt.execute(sql); // 注意:HSQLDB 2.7+ 默认允许;若报错,请确认版本并检查连接参数
}
}
// 使用示例
public static void main(String[] args) {
List<String> targetTables = Arrays.asList("users", "orders", "products", "categories");
try (Connection conn = DriverManager.getConnection(JDBC_URL, USER, PASSWORD)) {
// 导出到当前目录 backup.sql
exportTables(conn, targetTables, new File("backup.sql"));
System.out.println("✅ Export completed: backup.sql");
// (可选)清空目标表前先禁用外键约束(谨慎操作!)
// executeUpdate(conn, "SET DATABASE REFERENTIAL INTEGRITY FALSE");
// executeUpdate(conn, "TRUNCATE TABLE users, orders, products, categories RESTART IDENTITY");
// 导入恢复
importScript(conn, new File("backup.sql"));
System.out.println("✅ Import completed successfully.");
} catch (Exception e) {
e.printStackTrace();
}
}
}⚠️ 关键注意事项
- 权限与模式:PERFORM EXPORT SCRIPT 需在 PUBLIC 模式或显式指定模式(如 MYSCHEMA.TABLE_NAME),确保表存在且用户有 SELECT 权限;
- 脚本格式兼容性:导出内容默认不含 COMMIT,导入时建议在事务中执行(conn.setAutoCommit(false)),失败可回滚;
- 外键约束处理:导出脚本默认含 SET DATABASE REFERENTIAL INTEGRITY FALSE/TRUE 包裹,但若目标库已有数据,建议手动 TRUNCATE 或 DROP 表后再导入;
- 字符编码:务必使用 UTF-8 打开/写入 SQL 文件(如 new OutputStreamWriter(new FileOutputStream(...), StandardCharsets.UTF_8)),避免中文字段乱码;
- 版本要求:PERFORM EXPORT SCRIPT 自 HSQLDB 2.3.4 起稳定支持,推荐使用 2.7.x 最新版以获得最佳兼容性。
? 总结
HSQLDB 的 PERFORM EXPORT SCRIPT FOR TABLE ... DATA 是实现细粒度、可编程、零依赖表级备份的理想方案。相比全库 .tar 备份,它体积更小、恢复更精准、集成更简单。配合 Java JDBC 封装,可无缝嵌入自动化运维流程、测试数据准备或灰度发布场景。只需牢记三点:显式控制表名列表、统一处理编码与事务、验证目标环境约束状态——即可稳健支撑生产级数据迁移需求。
立即学习“Java免费学习笔记(深入)”;










