一、下面的关闭资源的示例中 (完整的示例) if(conn != null) 不是用来判断资源是否已经关闭了的。
而是用来避免空指针异常。
原因解释:
在JDBC 的一开始:
就定义了两个空值,如果往下执行,还没执行到给他们两个变量赋值就抛异常了,这个时候程序会catch一场然后执行finally里面的语句,但是这个时候set,state,conn都是空的,空的对象调用方法又会抛出nullpointexception,这个时候整个程序就崩溃了。所以在关闭之前必须先判空 。
二、close方法到底做了什么呢
java.sql.Connection.close()方法做的是立刻释放connection对象占用的数据库联接资源(断开网络连接,关闭io)。
并不是像我原以为的那样,close方法会简单地将conn对象设置为null。事实上,在调用close()之后,conn仍然不为null。
事实上比较完善的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资源释放的细节问题