在JDBC中,Connection,Statement和ResultSet应该多久关闭一次?

时间:2011-04-09 03:57:51

标签: java jdbc

每次查询后是否需要关闭它们并在每次查询开始时初始化?

2 个答案:

答案 0 :(得分:9)

始终即可。您需要在尽可能短的范围中获取和关闭它们,以避免资源泄漏,事务性问题和耗尽的连接池。如果不这样做会导致数据库迟早耗尽资源,导致“太多连接”等异常。

正常的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注入防护旁边)。获取和关闭连接是最昂贵的任务,但是发明了连接池。如果要重用相同的语句来执行批量插入/更新,则可以使用批处理。

另见:

答案 1 :(得分:0)

由于您不需要先前查询的结果,因此您需要初始化ResultSet。

如果需要,可以保留该语句,特别是应该保留PreparedStatements - 它们可以在数据库首次运行时进行预编译,这可以节省几秒钟:

"SELECT foo FROM bar WHERE a = ?" 

当然只有参数发生变化。