100分高分急问!求高手帮忙解决
我在一个函数里执行查询操作,返回结果ResultSet,在后面对ResultSet进行操作。
请问操作完之后该怎样关闭Statement和ResultSet?
因为涉及到大量的查询操作,为了防止内存溢出,需要正确、及时地释放连接。
代码如下所示:
//返回ResultSet结果的函数public java.sql.ResultSet executeQuery(String sexesql) throws SQLException {
java.sql.ResultSet rs = null;
Statement stmtDb = conn.createStatement();
try {
rs = stmtDb.executeQuery(sexesql);
} catch (SQLException e) {
System.err.println("ERROR IN Execute :" + sexesql + " : " + e);
} catch (NullPointerException e) {
}
return (rs);
//调用的代码while (rs.next()) {
long id = rs.getLong(1);
if (!isDeleted(id)) {
PathwayBean pb = new PathwayBean();
pb.selectDataFromDBByID(id);
list.add(pb);
}
}
rs.getStatement().close();//这两行关闭行吗?
rs.close();//这行应该可以省略吧?

解决方案 »

  1.   

    conn.close();//关闭数据库连接对象
    stmtDb.close();//关闭操作数据库对象
      

  2.   

    其实只要这样就行了:
    按照jdbc接口要求:   
    关闭connection后,statement及resultset会自动关闭   
    或者关闭statement后resultset会自动关闭。   
    具体实现是数据库厂商实现的。
      

  3.   

    我使用过这种情况!在第一个方法里面把链接CONN传入,后面调用的时候再关闭!
    不然就没办法及时关闭啦!
      

  4.   

    一般的做法,哪里拿到资源,哪里负责释放资源。比如你的那个方法,在你拿到resultset之后,应该把所有需要的操作放在方法里面进行,比如
      public void executeQuery(String sexesql) throws SQLException {
        java.sql.ResultSet rs = null;
        Statement stmtDb = conn.createStatement();
        try {
          rs = stmtDb.executeQuery(sexesql);
          call1(rs); // 所有的调用
          call2(rs);
          call3(rs);
        } catch (SQLException e) {
          System.err.println("ERROR IN Execute :" + sexesql + " : " + e);
        } catch (NullPointerException e) {} finally { // 这里关闭
          try {
            rs.close();
          } catch (Exception ex) {}
        }
        // return (rs);
      }
      

  5.   


    stmtDb.close();//关闭操作数据库对象
    conn.close();//关闭数据库连接对象 应该是这个顺序吧!!!
      

  6.   

    最好还是把数据封装一下 再处理这样把resultset对象 传来传去太不稳妥
      

  7.   

    ls说的是,呵呵..其实我觉得关闭了connection就可以了,大家可以抨击我的说法
      

  8.   

    1.楼主这样调用结构不好。首先你的Connection并没有关闭。
        rs.getStatement().close();//这个是官Statement
        rs.close();//这个是关闭ResultSe

    2.如果你的代码有异常抛出的话,你的Statement和ResultSet也都关不掉。
    3.最后ResultSet最好不要当成任何返回值返回。应该直接返回VO,数据对象。
    改进方法
    比如一个数据对象 Actor类。可以根据自己的需要更改。public class Actor {    private Long id;
        private String firstName;
        private String lastName;
        
        public String getFirstName() {
            return this.firstName;
        }
        
        public String getLastName() {
            return this.lastName;
        }
        
        public Long getId() {
            return this.id;
        }
        
        // 省略存取方法}
    调用代码注意要返回数据对象。下面的代码是最简单最基本的调用JDBC的方法。如果引入连接池呀,Hibernate或Spring会简化许多。public List<Actor> executeQuery(String sexesql) throws SQLException {
        List<Actor> actorList = new ArrayList<Actor>();
        Connection con = null; 
        Statement stmt = null;
        ResultSet rs = null
        try {
            con = DriverManager.getConnection(url, "sunny", ""); 
            stmt = con.createStatement(); 
            rs = stmtDb.executeQuery(sexesql);
            Actor actor = null;
            while (rs.next()) {
              actor = new Actor();
              actor.setId(rs.getLong("id"));
              actor.setFirstName(rs.getString("firstName"));
              actor.setLastName(rs.getString("lastName"));
              actorList.add(actor);
            }
        }catch (Exception e) {
           System.err.println("ERROR IN Execute :" + sexesql + " : " + e);
        }finally{  //在这里关闭资源才是正解
           try{       
            if(rs != null){
               rs.close();
            }
            if(stat != null){
               stat.close();
            }
            if(conn != null){
               conn.close();
            }
           }catch(Exception ignor){ //忽略这里的异常
           }
        }
        return actorList;
    }
      

  9.   

    我就觉得这样就ok,Try it,如果有错我和lz一起学习了      
    try{       
         if(conn != null)
            conn.close();  
          }catch(Exception e){ 
        }
     
      

  10.   

    从ResultSet中直接取出数据,封装成一个对象(自己根据数据结构写个类),然后再返回这个对象,不要直接返回ResultSet
    易载--个人网上资料收集必备工具。选中想收藏的文字(图片),右键选“收录到易载”,搞定!
      

  11.   


    close
    void close()
               throws SQLException立即释放此 ResultSet 对象的数据库和 JDBC 资源,而不是等待该对象自动关闭时发生此操作。 
    注:当生成 ResultSet 对象的 Statement 对象关闭、重新执行或用来从多个结果的序列检索下一个结果时,该 Statement 对象会自动关闭 ResultSet 对象。垃圾回收 ResultSet 对象时它也会自动关闭。
      

  12.   


    try 
    {
            con  = 
            stmt = 
            rs   = 
    }
    catch (Exception e)
    {
    }
    finally
    {  
           try
          {       
            if(rs != null)
            {
               rs.close();
               rs=null;        }
            if(stat != null)
            {
               stat.close();
               stat=null;        }
            if(conn != null)
            {
               conn.close();
               conn=null;        }
           }catch(Exception ignor){        }
    }
      

  13.   

    给你一个我写的完整的类
    package com.xiaolin.database;import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.sql.SQLException;public class DBManager {
    private Connection cnn;
    private PreparedStatement stmt;
    private ResultSet rs;
    public void OpenDB(){
    try {
    Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
    cnn=DriverManager.getConnection("jdbc:odbc:test","sa","");
    } catch (ClassNotFoundException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    } catch (SQLException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    }

    public ResultSet Query(String sql,Object[] objs){
    try {
    stmt=cnn.prepareStatement(sql);
    for (int i = 0; i < objs.length; i++) {
    stmt.setObject(i+1, objs[i]);
    }
    rs=stmt.executeQuery();
    } catch (Exception e) {
    e.printStackTrace();
    // TODO: handle exception
    }
    return rs;
    }

    public int Update(String sql,Object[] objs){
    int alterCount=0;
    try {
    stmt=cnn.prepareStatement(sql);
    for (int i = 0; i < objs.length; i++) {
    stmt.setObject(i+1, objs[i]);
    alterCount=stmt.executeUpdate();
    }
    } catch (Exception e) {
    e.printStackTrace();
    // TODO: handle exception
    }
    return alterCount;
    }

    public void CloseDB(){
    try {
    rs.close();
    stmt.close();
    cnn.close();
    } catch (SQLException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    }
    }
      

  14.   

       /**
         *
         * @param rs ResultSet
         * @param st Statement
         * @param conn Connection
         */
        public void closeConnections(ResultSet rs, Statement st, Connection conn)
        {
            if (rs != null)
            {
                try
                {
                    rs.close();
                }
                catch (SQLException e)
                {
                   
                }
            }
            if (st != null)
            {
                try
                {
                    st.close();
                }
                catch (SQLException e)
                {
                  
                }
            }
            if (conn != null)
            {
                try
                {
                    conn.close();
                }
                catch (SQLException e)
                {
                               }
            }
        }
      

  15.   

    按你的例子来说,我想按业务来关闭可能要好点
    比方在java_web中,按你一次请求结束以后再关闭连接
      

  16.   

        catch (SQLException e)
        {
            System.err.println("ERROR IN Execute :" + sexesql + " : " + e);
        } catch (NullPointerException e)
        {}
        finally
        {
            try
            {
                rs.close();
            } catch (Exception e) 
            {}
        }
    在catch后加finally代码块,无论有没有异常,都会执行   ,支持6楼
      

  17.   

    我有很多种查询,每个查询量又很大、很多。
    我的Connection用的是Singleton模式,并不是每种(批)查询完都关闭。
    请问这种设计好吗?还是应该每批查询完成之后,关闭所有的ResultSet、Statement和Connection,好呢?public static PathwayDBUtil getInstance(String name){
    if (dBUtilInstace == null){//用Singleton模式,只有一个实例
    dBUtilInstace = new PathwayDBUtil();
    url="jdbc:sqlserver://192.168.2.5:1433;DatabaseName="+name;
    dBUtilInstace.openConn();
    }
    return dBUtilInstace;
    }
    private void openConn() {//打开数据库连接
    try {
    Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
    conn = DriverManager.getConnection(url, user, pwd); } catch (Exception e) {
    e.printStackTrace();
    }
    }
    public void closeConn() {//在所有批次查询都查完后最后关闭数据库连接
    try {
    if (conn == null) {
    return;
    }
    conn.close();
    } catch (Exception e) {
    e.printStackTrace();
    } finally {
    try {
    conn.close();
    } catch (Exception e) {
    }
    }
    }
      

  18.   

    总是来晚,总结一下:
    1. 哪儿拿到的哪儿关闭。
    2. 关闭放 finally 里免得抛异常关闭执行不到。
    3. 数据流动方向 DB -> RS -> Bean -> View。
      

  19.   

    学习一下,
    一般关的时候习惯于在finally{}里按resultset, statement,connection关
    即使关闭connection后,statement及resultset会自动关闭  
      

  20.   


    看你的代码,你的dBUtilInstace 是Singleton的
    你的connection不是Singleton的。
      

  21.   

    finally{
         rs.close();
         con.close();
    }
      

  22.   

    第一写专门的方法判断需要关闭的对象是否为null后进行关闭,如果在发生异常程序不能继续往下运行的话,最好用fianlly块里关闭连接
      

  23.   

    就一个close方法,还用研究吗~~~
      

  24.   

    public static void close(Statement st, Connection con)
    {
    try
    {
    st.close();
    }catch(Exception e)
    {
    }

    try
    {
    con.close();
    }catch(Exception e)
    {
    }
    }

    public static void close(ResultSet rs, Statement st, Connection con)
    {
    try
    {
    rs.close();
    }catch(Exception e)
    {
    }
    close(st, con);
    }

    单独写一个类,专门用于连接、关闭的util
      

  25.   

    1。首先要放在finally里。
    2。如果只是想释放资源可以直接将rs和st赋值为null。
    3。建议写个JDBCUtil类,实现代码复用。
      

  26.   

    public static void closeConnection(DBConnection dbc) {
    if (dbc != null) {
    try {
    DBHT.remove(dbc.globeID);
    useCnt--;
    if (dbc.connection != null) {
    dbc.connection.close();
    String[] msg = { "DBFactory", "closeConnection",
    dbc + " 关闭成功" };
    TLoger.logDebug("2003", msg);
    } else {
    String[] msg = { "DBFactory", "closeConnection",
    dbc + " 不存在联接" };
    TLoger.logDebug("2003", msg);
    } } catch (SQLException ex) {
    String[] err = { "DBFactory", "closeConnection", dbc + " 关闭失败" };
    TLoger.logErr("3300", err, ex);
    }
    }
    }
      

  27.   

    最简单的 
    if(!conn.isClosed)
    {
      conn.closed();
    }
      

  28.   

    rs.getStatement().close();//这两行关闭行吗?
    rs.close();//这行应该可以省略吧?
    ==================================
    最好是这样:
    if(rs !=null){
      try{
        rs.close();
      }catch(Exception e){
         System.out.println(e);
      }
    }