我正在编写一个Java程序,它遍历用户提供的目录下的所有内容,查找h2数据库并显示其内容。这是我到目前为止编写的代码:
private void openDatabase(File file) {
try {
Class.forName("org.h2.Driver");
Connection connection;
try {
connection = DriverManager.getConnection("jdbc:h2:" + file.getAbsolutePath());
DatabaseMetaData md = connection.getMetaData();
ResultSet resultSet = md.getTables(null, null, "%", null);
while (resultSet.next()) {
System.out.println("TABLE: " + resultSet.getString(3));
}
connection.close();
} catch (SQLException e) {
e.printStackTrace();
} finally {
if (connection != null) {
try {
connection.close();
} catch (SQLException e2) {
e2.printStackTrace();
}
}
}
} catch (ClassNotFoundException e1) {
e1.printStackTrace();
}
}
它没问题 - 它找到(db)
并打印出其中的表格。只是一个问题。每次找到(db)
时,都会创建(db).h2.db
和(db).trace.db
。这意味着在我的程序的后续运行中,它会查找并扫描除(db)
之外的那些程序。这不是什么大问题,除了在第三次运行中,它创建(db).h2.db.h2.db
,(db).trace.db.h2.db
,(db).h2.db.trace.db
和(db).trace.db.trace.db
。等等。这是一个呈指数级增长的问题。
我做错了什么?我怎么能阻止它完全生成这些额外的文件,或者在它完成后自己清理它?
答案 0 :(得分:1)
对于H2数据库引擎,JDBC URL jdbc:h2:/directory/test
表示数据库内容存储在文件/directory/test.h2.db
中。这意味着,数据库URL与文件名完全匹配。
所以你可以做的是,而不是直接使用文件名,使用:
String fileName = file.getAbsolutePath();
if (!fileName.endsWith(".h2.db")) {
// not a H2 database
return;
}
String databaseName = fileName.substring(0, fileName.length() - ".h2.db".length());
String url = "jdbc:h2:" + databaseName;
答案 1 :(得分:1)
Thomas Mueller's Answer帮助清理了大部分额外的文件,但他遗漏的一件事是如何清理跟踪文件。我发现some documentation解释了如何摆脱这些文件。
您可以在连接网址中插入选项,以分号分隔。它们采用option_key = option_value形式。其中两个选项键是TRACE_LEVEL_SYSTEM_OUT
和TRACE_LEVEL_FILE
。它们中的每一个都可以设置为0(关闭),1(错误),2(信息)或3(调试)。
除了我使用正确打开数据库的选项编写的代码之外,没有创建额外的.h2.db文件,没有生成跟踪文件,并且信息会进入系统日志:
String path = file.getAbsolutePath();
String url = "jdbc:h2:" + path.substring(0, path.length()-6); // jdbc:h2 doesn't like file extensions in the path - remove the .h2.db
String options = ";TRACE_LEVEL_FILE=0;TRACE_LEVEL_SYSTEM_OUT=2"; // put info on the console, not in a log file
Connection connection = DriverManager.getConnection(url + options);