使用PreparedStatements和ResultSets是否每次使用时都会创建“新数据库实例”? 或者,换句话说,如果我使用PreparedStatement和ResultSet,我应该在每次使用后关闭它们还是在完成后关闭它们?
示例:
while (...){
p = connection.prepareStatement(...);
r = p.executeQuery();
while (r.next()) {
....
}
}
// We close at the end. Or there are any other p and r still opened...?
p.close();
r.close();
OR
while (...){
p = connection.prepareStatement(...);
r = p.executeQuery();
while (r.next()) {
....
}
p.close();
r.close();
}
注意:当然我会尝试并正确关闭,这只是一个例子。
答案 0 :(得分:5)
你应该关闭你打开的每一个。当您创建预准备语句或结果集时,数据库会为这些语句或结果集分配资源,关闭它们会告诉数据库释放这些资源(可能数据库最终会在超时期限后重新分配这些资源,但调用close会让数据库知道它可以继续前进并清理)。你的第二个例子更好,除了我在准备好的语句之前关闭结果集。
因此,如果包含try块,它将如下所示:
while (...){
PreparedStatement p = connection.prepareStatement(...);
try {
ResultSet r = p.executeQuery();
try {
while (r.next()) {
....
}
} finally {
try {
r.close();
} catch (SQLException e) {
// log this or something -- prevent these from masking original exception
}
}
}
finally {
try {
p.close();
} catch (SQLException e) {
// log this or something -- prevent these from masking original exception
}
}
}
从关闭中捕获异常很难看,但是如果在执行预准备语句期间抛出异常,或者在遍历结果集期间抛出异常,则需要确保看到它,而不是在抛出异常时抛出异常。关闭准备好的声明或结果集(由于某些网络故障,你无论如何都无法做任何事情)。
还要注意使用try-with-resources会有效,除非你有一个数据库操作成功但调用close导致异常的情况,那么异常将被抛出。
我建议人们使用spring-jdbc库(处理关闭所有内容),而不是手动启动iffy或verbose jdbc。
答案 1 :(得分:5)
第一种方式更好。
但是,如果您使用的SQL每次都相同,您应该知道可以重复使用预准备语句(因此名称为“准备好”)。例如:
//Note: try/catch/finally blocks removed for brevity
p = connection.prepareStatement(...);
while (...){
r = p.executeQuery();
while (r.next()) {
....
}
r.close();
}
p.close();
答案 2 :(得分:1)
即使您不想使用Spring,Apache DbUtils或类似产品,也要认识到这里有很多样板文件,您希望将它们从查询例程中分解出来,这样您就必须重复几次尽可能。