Re: [問題] 在物件被註銷時自動執行某些事

看板java作者 (LaPass)時間13年前 (2012/06/15 12:08), 編輯推噓2(200)
留言2則, 1人參與, 最新討論串5/7 (看更多)
說一下自己正在想,以及希望想找的解決方法 目前我看過跟資料庫的連線方式的libary,通常會包成這樣: 形式一: 取得連線 送入SQL從連線取得ResultSet while(ResultSet有資料) { 對資料做一些事 } 關閉ResultSet 關閉連線 通常在寫的時候,都會被包過,變成類似這樣 myDBHandler.open(); ResultSet rs = myDBHandler("SELECT * FROM USER"); while(rs.next()) { our.println("名稱:"+rs.getString("Name")); //下略 } rs.close(); myDBHandler.close(); 感覺起來還不錯,還挺簡潔的。 問題是,東西一多的話可能會變成這樣 myDBHandler.open(); ResultSet rs = myDBHandler("SELECT * FROM USER"); while(rs.next()) { our.println("名稱:"+rs.getString("Name")+"的統計資料"); //略 our.println("文章列表"); ResultSet subrs = myDBHandler("SELECT * FROM Post "+ " WHERE Pid = "+rs.getString("PostGroup")); while(subrs.next()) { //中略 } subrs.close(); subrs = myDBHandler("SELECT * FROM Mail "+ " WHERE Mid = "+rs.getString("PostGroup")); our.println("郵件列表"); while(subrs.next()) { //中略 } rs.close(); //下略 } rs.close(); myDBHandler.close(); 中間的東西可能會多達幾百行甚至一千多行..... 很多人喜歡這樣寫,但是這種程式風格會讓我覺得很痛苦 猛然一看很難看出上面那段程式哪邊有錯 有人注意到有個地方該打subrs.close(),卻打成rs.close()了嗎? 可能有,但是我通常不會注意到這種小地方 這種雜事我從來都認為應該是IDE或是程式結構要自己處理掉的。 我對程式的掌控能力不高,只有一個半螢幕而已 一個function中的東西,只要超過那樣的分量我就很容易亂掉 通常我自己寫給自己用的元件,會把麻煩事在底層都把它處理掉 在外層實際在用的時候,對一個物件的操作通常不會超過十行 那十行都是在處理不同元件間的掛勾、連結的操作 例如,發生什麼事的時候就去叫另外一個元件做什麼事,之類的 設定的部分寫完,需要人腦思考的部分就結束了 有點類似函數指標的觀念,雖然java沒有這種東西 但是可以用callback做出同樣的功能來 帶過我寫程式的人 雖然才兩個,但兩個都想把我這種寫法改掉 他們覺得程式應該是一行行執行下去,而不是東跳西跳..... 雖然在寫別人的code的時候會用他們的辦法去寫 但是我在寫自己的code的時候,會照自己的架構下去寫 不這樣自己想的寫,寫程式就沒樂趣了。 離題了 那,另外一種資料庫連線的寫法是把 while(rs.next()) { our.println("名稱:"+rs.getString("Name")); //下略 } rs.close(); 這一段包在一個Method當中 變成類似 MyDBHandler myDBHandler = new MyDBHandler() List<User> userList = myDBHandler.getUser(); myDBHandler.close(); 之前我看過hibernate的範例,感覺起來就類似這樣 (雖然最特殊的是設定檔,得為每個資料表建立一個class) 程式比較不會被一大串迴圈給包著 但是連線還是得自己關 由於還要開、關連線,對我習慣的架構而言,是個問題 這會讓每個有用到資料庫的元件都出現lifecycle 變成說,我還要另外去管元件的死活 每個東西在不用的時候都得呼叫個close()之類的 或是取得資料的掛勾動作 要由1個掛勾點(取得資料),變成3個掛勾點要處理(開啟,取得資料,關閉) 兩種方式都很糟糕..... 另外 try-with-resources Statement 或是 把整個資料庫連線連線流程給包在一個Method,例如: List<User> getUser() { List<User> listUser=new ArrayList<User>(); myDBHandler.open(); ResultSet rs = myDBHandler("SELECT * FROM USER"); while(rs.next()) { listUser.add(/*中略*/); } rs.close(); myDBHandler.close(); return listUser; } 這個雖然不會讓使用資料庫的元件出現lifecycle 但是每次取得資料時都會開、關一次連線 怎麼想都覺得,容易會造成短時間大量開、關連線的問題啊 而且,除了Connection之外還有Statement跟ResultSet要處理 Statement跟ResultSet原生的功能也不少 讓外層直接用這個,彈性似乎比較大 但麻煩的是,這幾個也都有close之類的東西要處理 比Connection更麻煩的是...... 在stackoverflow有看到說Connection是執行緒安全的物件 雖然看別人的建議是一條執行緒用一個Connection物件就好 但不小心重複使用到應該也不會造成大問題 不過Statement就不能這樣了 Statement在取得ResultSet的時候,會把上一次的ResultSet關掉 要防止這種風險,似乎只能每次new一個Statement -- -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 61.59.16.65

06/18 15:33, , 1F
我跟原PO一樣看到太多code無法handle,這時候就是
06/18 15:33, 1F

06/18 15:39, , 2F
使用Framwork的好時機了!!
06/18 15:39, 2F
文章代碼(AID): #1FshKrVe (java)
討論串 (同標題文章)
文章代碼(AID): #1FshKrVe (java)