1 import java.sql.Connection; 2 import java.sql.DriverManager; 3 import java.sql.ResultSet; 4 import java.sql.SQLException; 5 import java.sql.Statement; 6 7 public class OraclDao { 8 9 private Connection conn = null; 10 11 public void initConnection(String url, String uid, String pwd) {// 初始化 12 String className = "oracle.jdbc.driver.OracleDriver"; 13 try { 14 Class.forName(className); 15 conn = DriverManager.getConnection(url, uid, pwd); 16 } catch (ClassNotFoundException e) { 17 e.printStackTrace(); 18 } catch (SQLException e) { 19 e.printStackTrace(); 20 } 21 } 22 23 public void closeConnection() { 24 if (conn != null) { 25 try { 26 conn.close(); 27 conn = null; 28 } catch (SQLException e) { 29 e.printStackTrace(); 30 } 31 } 32 } 33 34 public ResultSet executeSQL(String sql) throws SQLException { 35 Statement stmtt = null; 36 ResultSet rs = null; 37 try { 38 stmtt = conn.createStatement(); 39 rs = stmtt.executeQuery(sql); 40 /* 41 * while (rs.next()) { System.out.println("sdfsdf");// TODO } 42 */ 43 return rs; 44 } catch (SQLException e) { 45 e.printStackTrace(); 46 } finally { 47 if (rs != null) { 48 try { 49 rs.close(); 50 rs = null; 51 } catch (SQLException e) { 52 e.printStackTrace(); 53 } 54 } 55 if (stmtt != null) { 56 try { 57 stmtt.close(); 58 stmtt = null; 59 } catch (SQLException e) { 60 e.printStackTrace(); 61 } 62 } 63 // closeConnection(); 64 } 65 } 66 67 public static void main(String[] args) { 68 String url = "jdbc:oracle:thin:@localhost:" + 1521 + ":orcl"; 69 OraclDao oraclDao = new OraclDao(); 70 oraclDao.initConnection(url, "SCOTT", "tiger"); 71 72 try { 73 ResultSet rs = oraclDao.executeSQL("select * from scott.userinfo"); 74 75 while (rs.next()) { 76 System.out.println("sdfsdf");// TODO 77 } 78 } catch (SQLException e) { 79 e.printStackTrace(); 80 } 81 oraclDao.closeConnection(); 82 } 83 }
如上程序,執行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的區別。