作者LaPass (LaPass)
看板java
标题Re: [问题] 在物件被注销时自动执行某些事
时间Fri Jun 15 12:08:18 2012
说一下自己正在想,以及希望想找的解决方法
目前我看过跟资料库的连线方式的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
1F:推 tomap41017:我跟原PO一样看到太多code无法handle,这时候就是 06/18 15:33
2F:推 tomap41017:使用Framwork的好时机了!! 06/18 15:39