这可能看起来像一个重复的问题,但事实并非如此。我试着在48小时内找到答案而没有结果。
首先,关闭PreparedStatment
& SQLite JDBC Connection中需要ResultSet
吗?因为我无法这样做
try {
Class.forName(database.getJDBC_DRIVER());
cnn = DriverManager.getConnection(database.getDB_URL());
p = cnn.prepareStatement(query);
rs = p.executeQuery();
p.close();
cnn.close();
} catch (SQLException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} finally {
try {
System.out.println(p.isClosed());
if (cnn != null) cnn.close();
System.out.println(p.isClosed());
} catch (SQLException e) {
e.printStackTrace();
}
}
如您所见,我在try块中关闭了PreparedStatement
。但是,当我检查try块外部的状态时,结果总是为false。 (这意味着它没有关闭)。
此外,如果我在finally块中有下面的代码,它会抛出一个错误,说明连接已关闭。对于该做什么,我感到非常困惑。我应该保持原样。我的代码不会有一些泄漏吗?
} finally {
try {
if (p != null) p.close(); *// It errors out here...*
if (cnn != null) cnn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
下面是堆栈跟踪 -
java.sql.SQLException: [SQLITE_ERROR] SQL error or missing database (Connection is closed)
at org.sqlite.core.DB.newSQLException(DB.java:890)
at org.sqlite.core.CoreStatement.internalClose(CoreStatement.java:109)
at org.sqlite.jdbc3.JDBC3Statement.close(JDBC3Statement.java:35)
at tg.cat.DropDown.getData(DropDown.java:28)
at tg.loginscreen.LoginScreenLayout.<init>(LoginScreenLayout.java:22)
at tg.cat.CatMain.getScene(CatMain.java:27)
at tg.cat.CatMain.start(CatMain.java:18)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$159(Unknown Source)
at com.sun.javafx.application.LauncherImpl$$Lambda$53/855499929.run(Unknown Source)
at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$172(Unknown Source)
at com.sun.javafx.application.PlatformImpl$$Lambda$45/186276003.run(Unknown Source)
at com.sun.javafx.application.PlatformImpl.lambda$null$170(Unknown Source)
at com.sun.javafx.application.PlatformImpl$$Lambda$48/1635925971.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl.lambda$runLater$171(Unknown Source)
at com.sun.javafx.application.PlatformImpl$$Lambda$47/237061348.run(Unknown Source)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(Unknown Source)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$null$145(Unknown Source)
at com.sun.glass.ui.win.WinApplication$$Lambda$36/2117255219.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
答案 0 :(得分:3)
无论是否抛出异常,都会执行finally
块。因此,您无需使用它来再次关闭连接 ,而是将其用作关闭连接的唯一位置。其次,请注意,关闭连接不会将变量重置为null
:
try {
Class.forName(database.getJDBC_DRIVER());
cnn = DriverManager.getConnection(database.getDB_URL());
p = cnn.prepareStatement(query);
rs = p.executeQuery();
} catch (SQLException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} finally {
try {
if (rs != null) {
rs.close();
}
if (p != null) {
p.close();
}
if (cnn != null) {
cnn.close();
}
} catch (SQLException e) {
System.err.println("Can't close an object, not much I can do");
}
}
答案 1 :(得分:1)
Mureinik是对的,但更好的是使用try-with-resources功能,这样你甚至不必担心首先关闭任何东西(手动)。
try (Connection cnn = DriverManager.getConnection(database.getDB_URL());
PreparedStatement p = cnn.prepareStatement(query)) {
// prepare your statement
try (ResultSet rs = p.executeQuery()) {
// process result set
}
} catch (SQLException e) {
throw new RuntimeException("Unexpected SQLException", e);
}