【发布时间】:2011-08-01 22:42:25
【问题描述】:
是否需要在每次查询后关闭并在每次查询开始时进行初始化?
【问题讨论】:
是否需要在每次查询后关闭并在每次查询开始时进行初始化?
【问题讨论】:
总是。您需要在尽可能短的范围内获取并关闭它们,以避免资源泄漏、事务问题和耗尽的连接池。不这样做会导致数据库迟早会耗尽资源,从而导致“连接过多”等异常。
正常的 JDBC 习惯用法如下,所有资源都在同一个 try-with-resources 块中打开和:
public List<Entity> list() throws SQLException {
List<Entity> entities = new ArrayList<Entity>();
try (
Connection connection = database.getConnection();
PreparedStatement statement = connection.prepareStatement(SQL_LIST);
ResultSet resultSet = statement.executeQuery();
) {
while (resultSet.next()) {
entities.add(map(resultSet));
}
}
return entities;
}
或者当您还没有使用 Java 7 时:
public List<Entity> list() throws SQLException {
List<Entity> entities = new ArrayList<Entity>();
Connection connection = null;
PreparedStatement statement = null;
ResultSet resultSet = null;
try {
connection = database.getConnection();
statement = connection.prepareStatement(SQL_LIST);
resultSet = statement.executeQuery();
while (resultSet.next()) {
entities.add(map(resultSet));
}
} finally {
if (resultSet != null) try { resultSet.close(); } catch (SQLException logOrIgnore) {}
if (statement != null) try { statement.close(); } catch (SQLException logOrIgnore) {}
if (connection != null) try { connection.close(); } catch (SQLException logOrIgnore) {}
}
return entities;
}
使用PreparedStatement 将使您受益于语句的数据库缓存(在正确使用时可防止 SQL 注入)。获取和关闭连接是最昂贵的任务,但连接池就是为此而发明的。如果您想重复使用相同的语句来进行批量插入/更新,那么您可以使用批处理。
【讨论】:
database.getConnection() 返回一个池连接。如果您正在开发基于 Servlet 的应用程序,请从这里开始:stackoverflow.com/q/2299469
由于您不想要上一个查询的结果,因此您当然需要初始化 ResultSet。
如果再次需要,可以保留该语句,特别是应保留 PreparedStatements - 它们可以在数据库第一次运行时预编译,从而节省一些时间:
"SELECT foo FROM bar WHERE a = ?"
如果只是参数改变,当然。
【讨论】: