JDBC资源释放的细节问题

一、下面的关闭资源的示例中 (完整的示例 if(conn != null) 不是用来判断资源是否已经关闭了的。

而是用来避免空指针异常。

原因解释:

在JDBC 的一开始:

就定义了两个空值,如果往下执行,还没执行到给他们两个变量赋值就抛异常了,这个时候程序会catch一场然后执行finally里面的语句,但是这个时候set,state,conn都是空的,空的对象调用方法又会抛出nullpointexception,这个时候整个程序就崩溃了。所以在关闭之前必须先判空 。

二、close方法到底做了什么呢

java.sql.Connection.close()方法做的是立刻释放connection对象占用的数据库联接资源(断开网络连接,关闭io)。

并不是像我原以为的那样,close方法会简单地将conn对象设置为null。事实上,在调用close()之后,conn仍然不为null。

扫描二维码关注公众号,回复: 19578 查看本文章

事实上比较完善的finally的写发中既调用close(),又将对象置空。

package com.javy.jdbc;  
  
import java.sql.Connection;  
import java.sql.DriverManager;  
import java.sql.ResultSet;  
import java.sql.SQLException;  
import java.sql.Statement;  
  
import com.mysql.jdbc.Driver;  
  
public class JdbcDemo1 {  
  
    public static void main(String[] args) {  
        Connection conn = null;  
        Statement state = null;  
        ResultSet set = null;  
        try {  
            // 注册数据库驱动  
            DriverManager.registerDriver(new Driver());  
            Class.forName("com.mysql.jdbc.Driver");  
            // 获取数据库连接  
            conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb", "root", "");  
            // 获取传输器对象  
            state = conn.createStatement();  
            // 利用传输器对象执行sql语句  
            set = state.executeQuery("select * from emp");  
            while (set.next()) {  
                System.out.println(set.getString("name"));  
            }  
        } catch (SQLException e) {  
            // TODO Auto-generated catch block  
            e.printStackTrace();  
        } catch (ClassNotFoundException e) {  
            // TODO Auto-generated catch block  
            e.printStackTrace();  
        } finally {  
            try {  
                conn.close();  
  
            } catch (SQLException e) {  
                // TODO Auto-generated catch block  
                e.printStackTrace();  
            } finally {  
                conn = null;  
            }  
            try {  
                set.close();  
  
            } catch (SQLException e) {  
                // TODO Auto-generated catch block  
                e.printStackTrace();  
            } finally {  
                set = null;  
            }  
  
            try {  
                state.close();  
  
            } catch (SQLException e) {  
                // TODO Auto-generated catch block  
                e.printStackTrace();  
            } finally {  
                state = null;  
            }  
  
        }  
    }  
  
}  

对于上面的代码。在关闭时每一个close() 都try catch的原因是,关闭时可能发生异常,这样剩下的就关不了了。所以每一个都要捕获。

三、对于ResultSet,Statement,Connection的关闭有这样一种关系:关闭一个Statement会把它的所有的ResultSet关闭掉,关闭一个Connection会把它的所有的Statement关闭掉。

但推荐先从小的关ResultSet-->Statement-->Connection

关于更多细节可以参考篇:JDBC:JDBC资源释放的细节问题

                                            java.sql.Connection的close方法究竟干了啥(以MySQL为例)

猜你喜欢

转载自my.oschina.net/zjllovecode/blog/1618446