Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/384.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java-Can';连接关闭后,请不要使用ResultSet_Java_Sql_Jdbc - Fatal编程技术网

Java-Can';连接关闭后,请不要使用ResultSet

Java-Can';连接关闭后,请不要使用ResultSet,java,sql,jdbc,Java,Sql,Jdbc,我在关闭MySQL连接时遇到问题 我得到了一个错误: java.sql.SQLException:结果集关闭后不允许操作 我的代码: public static ResultSet sqlquery (String query) { ResultSet rs=null; Connection connection=null; Statement st=null; try{ Class.forName("com.mysql.jdbc.Driver"); conne

我在关闭MySQL连接时遇到问题

我得到了一个错误:

java.sql.SQLException:结果集关闭后不允许操作

我的代码:

public static ResultSet sqlquery (String query)
{
 ResultSet rs=null;
 Connection connection=null;
 Statement st=null;
 try{   
     Class.forName("com.mysql.jdbc.Driver");
     connection = DriverManager.getConnection("databaseadress","username","password");
     st = connection.createStatement();  
     rs = st.executeQuery(query);

    }catch(SQLException e){System.out.println("SQL error: " + e);}
      catch(Exception e){System.out.println("Error: " + e);}
       finally {
       try{
          if(rs != null) rs.close();
          if(st!= null) st.close();
          if(connection != null)  connection.close();
  }catch(SQLException e){System.out.println("SQL error : " + e);}

    }
     return rs;
}

这就是JDBC的工作方式。在代码中,您关闭了
结果集
连接
,之后
结果集
不再可用。如果您想让它可用,您必须将它(以及
连接
)保持打开状态


但是,如果您返回
结果集
,则应该重构代码,以便调用方法提供
连接

JDBC不会在结果集中返回查询的所有结果,因为可能有太多的结果而无法急切地全部获取。相反,它为您提供了一些可用于检索结果的内容,但当连接关闭时,这些内容就会消失。因此,当您在关闭数据库连接后从方法传回它时,其他任何东西都不能使用它

您可以改为让此方法使用resultSet填充对象或对象集合,然后将填充的对象传递回

如果您将代码更改为传入一个行映射器(它获取一个resultSet并传回一个用resultSet中的当前行填充的对象),并使用它来填充一个您传回的容器对象,那么您将拥有与您编写的一样可重用的东西,但这实际上是可行的,因为它不依赖于在呼叫结束后保持连接打开

下面是使用rowmapper重写的示例代码,消除了一些不必要的异常捕获,并修复了在某些情况下会阻止连接关闭的错误:

public static List<T> sqlquery (String query, RowMapper<T> rowMapper) throws SQLException
{
    Connection connection=null;
    Statement st=null;
    ResultSet rs=null;
    // don't need Class.forName anymore with type4 driver     
    connection = DriverManager.getConnection("databaseadress","username","password");
    st = connection.createStatement();  
    rs = st.executeQuery(query);
    List<T> list = new ArrayList<T>();
    while (rs.next()) {
        list.add(rowMapper.mapRow(rs));
    }
    // don't let exception thrown on close of
    // statement or resultset prevent the
    // connection from getting closed
    if(rs != null) 
        try {rs.close()} catch (SQLException e){log.info(e);}
    if(st!= null) 
        try {st.close()} catch (SQLException e){log.info(e);}
    if(connection != null)  
        try {connection.close()} catch (SQLException e){log.info(e);}
    return list;
}
publicstaticlist-sqlquery(字符串查询,行映射器-行映射器)抛出SQLException
{
连接=空;
语句st=null;
结果集rs=null;
//type4驱动程序不再需要Class.forName
connection=DriverManager.getConnection(“数据库地址”、“用户名”、“密码”);
st=connection.createStatement();
rs=st.executeQuery(查询);
列表=新的ArrayList();
while(rs.next()){
添加(rowMapper.mapRow(rs));
}
//不要让异常在关闭时抛出
//语句或结果集阻止
//连接无法关闭
如果(rs!=null)
尝试{rs.close()}catch(SQLException e){log.info(e);}
如果(st!=null)
请尝试{st.close()}catch(SQLException e){log.info(e);}
if(连接!=null)
请尝试{connection.close()}catch(SQLException e){log.info(e);}
退货清单;
}
如上图所示,如果您没有单独捕获在关闭时抛出的每个异常,那么如果语句或结果集在关闭时抛出异常,则可能无法关闭连接

这与spring jdbc的功能类似,它将定义为:

公共接口行映射器{
T mapRow(ResultSet,intrownum)抛出SQLException;
}
下一步是参数化查询,这样您就不必
将参数值括在引号中或担心sql注入。有关SpringJDBC如何处理此问题的示例,请参见。这里的长期答案是,采用spring jdbc或类似的东西比零碎地重新创建要好。

一旦连接关闭,您就不能再使用任何资源(语句、准备好的语句、结果集),所有这些资源都会自动关闭。因此,您需要在资源打开时执行所有处理

尝试填充并返回DTO,这样您就可以在不保持连接活动的情况下获得所需的数据

RowSetFactory factory = RowSetProvider.newFactory();
CachedRowSet rowset = factory.createCachedRowSet();
rowset.populate(ResultSet data)

/*现在,您可以关闭连接并准备语句*/

我不是数据库专家,但在我看来,在完成结果集之前,您不想关闭连接。那么,当您更改代码以反映这一点时会发生什么呢?为什么不从方法内的ResultSet中提取数据,并返回您希望使用数据创建的任何对象的ArrayList,然后从方法中返回此列表?您关闭了ResultSet,因此所有内容都将被删除。你为什么要用它?在关闭数据之前提取数据并返回数据异常发生在哪一行代码上?你确定这是你在这里显示的吗?看来他正在返回
ResultSet
对象,并在后面未显示的代码中获取异常。@JimGarrison是的,我知道。我希望通过检查堆栈跟踪,他会发现这一点。谢谢,这可能是最好的方法:)谢谢,解释了ResultSet是如何处理的
RowSetFactory factory = RowSetProvider.newFactory();
CachedRowSet rowset = factory.createCachedRowSet();
rowset.populate(ResultSet data)