Re: [問題] 在物件被註銷時自動執行某些事
說一下自己正在想,以及希望想找的解決方法
目前我看過跟資料庫的連線方式的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
06/18 15:33, 1F
推
06/18 15:39, , 2F
06/18 15:39, 2F
討論串 (同標題文章)
以下文章回應了本文:
完整討論串 (本文為第 5 之 7 篇):