import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement; public class OraclDao { private Connection conn = null; public void initConnection(String url, String uid, String pwd) {// 初始化
String className = "oracle.jdbc.driver.OracleDriver";
try {
Class.forName(className);
conn = DriverManager.getConnection(url, uid, pwd);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
} public void closeConnection() {
if (conn != null) {
try {
conn.close();
conn = null;
} catch (SQLException e) {
e.printStackTrace();
}
}
} public ResultSet executeSQL(String sql) throws SQLException {
Statement stmtt = null;
ResultSet rs = null;
try {
stmtt = conn.createStatement();
rs = stmtt.executeQuery(sql);
/*
* while (rs.next()) { System.out.println("sdfsdf");// TODO }
*/
return rs;
} catch (SQLException e) {
e.printStackTrace();
} finally {
if (rs != null) {
try {
rs.close();
rs = null;
} catch (SQLException e) {
e.printStackTrace();
}
}
if (stmtt != null) {
try {
stmtt.close();
stmtt = null;
} catch (SQLException e) {
e.printStackTrace();
}
}
// closeConnection();
}
} public static void main(String[] args) {
String url = "jdbc:oracle:thin:@localhost:" + 1521 + ":orcl";
OraclDao oraclDao = new OraclDao();
oraclDao.initConnection(url, "SCOTT", "tiger"); try {
ResultSet rs = oraclDao.executeSQL("select * from scott.userinfo"); while (rs.next()) {
System.out.println("sdfsdf");// TODO
}
} catch (SQLException e) {
e.printStackTrace();
}
oraclDao.closeConnection();
}
}

如上程序,执行main函数,在executeSQL方法里面ResultSet是有值的,但是当返回到外层(main),发现rs是null。经仔细分析,这一奇怪的现象产生的原因是ResultSet是和连接相关的。(即如果关闭了statement、connection或resultset,则resultset就也没有值了)

当生成 ResultSet 对象的 Statement 对象关闭、重新执行或用来从多个结果的序列获取下一个结果时,ResultSet 对象将自动关闭。

本例中,执行executeSQL方法时应该是先执行finally里的,再执行return rs;finally里关闭了resultset和statement,所以返回的resultset的值成为了null。

解决的方法:

1、将查询得到的resultSet中的值保存在arrayList等中,executeSQL方法的返回值类型不要写成ResultSet类型的。

2、finally中的关闭操作往后放,即不写在executeSQL方法里,而是在外层处理过resultset后再关闭。

其他:resultset算是比较特殊的了。如果一个函数返回值是int型,程序中假设返回变量a,a的值是5.在finally块中又将a的值置为-1;则上层接收到的返回值仍然是5.虽然先执行finally块,后执行return语句,也不会改变return的值。此时返回的是5,但a的真实值应该是变为-1了。注意这个和resultSet的区别。

04-14 17:07