在我想要返回ResultSet时关闭JDBC连接的位置

Alo*_*ong 18 java connection jdbc resultset

ResultSet当我关闭时,似乎会自动关闭Connection.但我想返回ResultSet并在另一种方法中使用它,然后我不知道在哪里关闭ConnectionPreparedStatement.

public ResultSet executeQuery(String sql, String[] getValue)
{
    Connection conn = null;
    PreparedStatement pstmt = null;
    ResultSet rs = null;
    try
    {
        conn = getConn();
        pstmt = conn.prepareStatement(sql);
        if (getValue != null)
        {
            for (int i = 0; i < getValue.length; i++)
            {
                pstmt.setString(i + 1, getValue[i]);
            }
        }
        rs = pstmt.executeQuery();
    } catch (Exception e)
    {
        e.printStackTrace();
        closeAll(conn, pstmt, rs);
    }
    return rs;
}
Run Code Online (Sandbox Code Playgroud)

我已经closeAll(conn, pstmt, null);进入了catch区块,因为我发现如果我把它放在finally块中,我会rs在它返回之前立即丢失.现在,当我想要关闭时rs,我无法关闭connpstmt.有什么解决方案吗?

Mir*_*uta 31

使用CachedRowSet用于断开后持有信息

Connection con = ...
ResultSet rs = ...

CachedRowSet rowset = new CachedRowSetImpl();
rowset.populate(rs);

con.close()
Run Code Online (Sandbox Code Playgroud)


z5h*_*z5h 20

一种干净的编码方式是传入一个具有回调方法的对象,该方法采用结果集.

您的另一个方法使用回调方法使用它的resultSet处理代码创建对象,并将其传递给执行SQL的方法.

这样,您的SQL和DB代码保留在它所属的位置,您的结果集处理逻辑更接近于您使用数据的位置,并且您的SQL代码会在应该的时候进行清理.

  interface ResultSetCallBack{
    void handleResultSet(ResultSet r);
  }

  void executeQuery(..., ResultSetCallBack cb){
    //get resultSet r ...
    cb.handleResultSet(r);
    //close connection
  }

  void printReport(){
    executeQuery(..., new ResultSetCallBack(){
      public void handleResultSet(ResultSet r) {
        //do stuff with r here
      }
    });
  }
Run Code Online (Sandbox Code Playgroud)


Bal*_*usC 5

绝对不应在要获取关闭方法块的方法块外部将其传递ResultSet(或StatementConnection以避免资源泄漏。一种常见的做法是将映射ResultSet到一个List<Data>where,那里Data只是一个代表感兴趣数据的javabean对象。

这是一个基本示例:

public class Data {
    private Long id;
    private String name;
    private Integer value;
    // Add/generate public getters + setters.
}
Run Code Online (Sandbox Code Playgroud)

这是如何正确处理的基本示例:

public List<Data> list() throws SQLException {
    Connection connection = null;
    PreparedStatement statement = null;
    ResultSet resultSet = null;
    List<Data> list = new ArrayList<Data>();

    try {
        connection = database.getConnection();
        statement = connection.prepareStatement("SELECT id, name, value FROM data");
        resultSet = statement.executeQuery();
        while (resultSet.next()) {
            Data data = new Data();
            data.setId(resultSet.getLong("id"));
            data.setName(resultSet.getString("name"));
            data.setValue(resultSet.getInt("value"));
            list.add(data);
        }
    } 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 list;
}
Run Code Online (Sandbox Code Playgroud)

您可以按以下方式使用它:

List<Data> list = dataDAO.list();
Run Code Online (Sandbox Code Playgroud)

要了解有关JDBC最佳实践的更多信息,您可能会发现这篇基本的入门文章也很有用。