选择显示字体大小

查询数据库后返回iterator

既然我们把数据库访问封装起来了,那么如果查询数据库返回的是一系列结果,比如我们从数据库中得到所有人的用户名,然后在jsp页面显示出来。

这里就有一个普遍疑问,我这个javabean是返回resultset到jsp中还是collection?

我曾经有段时间图省事,直接返回resultset,然后在我的jsp页面中是大量的resultset遍历。这其实还是将数据层和显示层混淆在一起。在ejb cmp中,返回的是collection,这样偶合性降低,不用在修改数据库结构后,一直修改程序到前台jsp页面,这和以前的php asp开发方式没两样。

但是返回collection效率不是很高,因为意味着在内存中要开辟一个内存存放所有的结果。

我看了http://builder.com.com/article.jhtml?id=u00220020814r4b01.htm这篇文章后,觉得启发很大,返回iterator就可以了。

iterator也是个模式,在jive中大量使用了iterator,我以前很奇怪,为什么他没事自己写个iterator,现在知道原因了,这样节省内存,而且效率高。

看下面比较:

public list getusers() {
resultset rs = userdbquery();
list retval = new arraylist();
while (rs.next()) {
retval.add(rs.getstring(1));
}
return retval;
}

上面是个我们采取返回collection后最常用的方法,将resultset中的用户名加入list再返回,显然这很耗费内存。

使用iterator返回:

public iterator getusers() {
final resultset rs = userdbquery();
return new iterator() {
private object next;

public boolean hasnext() {
if (next == null) {
if (! rs.next()) {
return false;
}
next = rs.getstring(1);
}
return true;
}

public object next() {
if (! hasnext()) {
throw new nosuchelementexception();
}
string retval = next;
next = null;
return retval;
}

public void remove() {
throw new unsupportedoperationexception("no remove allowed");
}
}
}

这里返回的是一个内部类,其实你可以象jive那样,专门做个iterator类,这样,这里写得就不那么难看,你自己定义的iterator和collection中的iterator没有任何关系,自己定义了三个方法 hasnext(); next(); remove();这样看上去和collection的iterator是一样的。

从自己作的这个iterator类中看到,这个javabean只是做了一个指针传递作用,将调用本javabean的指针传递到resultset,这样既提高了效率,节约了内存,又降低了偶合性,这是堪称中间件典型的示范。

既然返回iterator这么好,有人经常用到一个简单的返回iterator方法:
public iterator getusers() {
resultset rs = userdbquery();
list list = new arraylist()
while (rs.next()) {
list.add(rs.getstring(1));
}
return list.iterator();
}


这其实和直接返回list没区别,还是浪费内存。


就此篇文章引起争论:

1.关闭数据库连接rs是否还能使用?

http://dev.csdn.net/develop/article/17/17705.shtm

如下:


在connection上调用close方法会关闭statement和resultset吗?

级联的关闭这听起来好像很有道理,而且在很多地方这样做也是正确的,通常这样写
connection con = getconnection();//getconnection is your method
preparedstatement ps = con.preparestatement(sql);
resultset rs = ps.executequery();
……
///rs.close();
///ps.close();
con.close();  // no!
这样做的问题在于connection是个接口,它的close实现可能是多种多样的。在普通情况下,你用drivermanager.getconnection()得到一个connection实例,调用它的close方法会关闭statement和resultset。但是在很多时候,你需要使用数据库连接池,在连接池中的得到的connection上调用close方法的时候,connection可能并没有被释放,而是回到了连接池中。它以后可能被其它代码取出来用。如果没有释放statement和resultset,那么在connection上没有关闭的statement和resultset可能会越来越多,那么……
相反,我看到过这样的说法,有人把connection关闭了,却继续使用resultset,认为这样是可以的,引发了激烈的讨论,到底是怎么回事就不用我多说了吧。(作者意思是:rs的资源没有释放,还用的是连接池中的conn)

所以我们必须很小心的释放数据库资源,下面的代码片断展示了这个过程

connection con = null;
preparedstatement ps = null;
resultset rs = null;

try {
    con = getconnection();//getconnection is your method
    ps = con.preparestatement(sql);
    rs = ps.executequery();
    ///...........
}
catch (sqlexception ex) {
    ///错误处理
}
finally{
    try {
        if(ps!=null)
            ps.close();
    }
    catch (sqlexception ex) {
        ///错误处理
    }
    try{
        if(con!=null)
            con.close();
    }
    catch (sqlexception ex) {
        ///错误处理
    }
}

很麻烦是不是?但为了写出健壮的程序,这些处理是必须的。

大意如下:

如果不使用连接池机制, 关闭connection, 必然关闭resultset!
如果使用连接池, 所谓的关闭connection, 其实是将连接返回给了连接池,
连接对象依然存在, 所以这实际上不叫关闭!

2.性能问题

如果不是为了模式,用resultset遍历是最快的,比放进collection在遍历要快很多,装进collection不也是resultset的遍历吗。在jsp中遍历resultset占用数据库资源的说法是不对的。jsp的后台实现就是servlet。为了模式性能上是要付出代价的。

要是你在collection里面依然采用直接包装resultset的方式,在性能上没有丝毫好处。唯一的好处是对jsp程序员屏蔽了rs的访问。
collection需要对java.sql.resultset的数据进行page的包装。才有性能上的效果。


 


关键字 本文所属关键字

相关 与本文相关文章

分类 所有文章关键字导航

源码编程相关

Java   Asp   PHP   .Net   XML   C/C++   CGI   VB   Jsp   J2ee   J2se   J2me   EJB   Servlet   Tomcat   Resin   Struts   Weblogic   Eclipse   ANT   GUI   JMS   Web servise   IDEA   Webphere   Hibernate   Spring   Jboss   Applet   Swing   Socket   Javamail   Perl   Ajax   P2P   安全   模式   框架   测试   开源   游戏

SQL数据库相关

My-SQL   Ms-SQL   Access   DB2   Oracle   Sybase   SQLserver   索引   存储过程   加密   数据库   分页   视图  

手机无线相关

3G   Wap   CDMA   GRPS   GSM   IVR   彩信   短信   无线   增值业务

网页设计制作相关

HTML   CSS   网页配色   网页特效   Javascript   VBscript   Dreamweaver   Frontpage   JS   Web   网站设计

网站建设推广相关

建站经验   网站优化   网站排名   推广   Alexa

操作系统/服务器相关

Windows XP   Windows 2000   Windows 2003   Windows Me   Windows 9.x   Linux   UNIX   注册表   操作系统   服务器   应用服务器

图形图像多媒体相关

Photoshop   Fireworks   Flash   Coreldraw   Illustrator   Freehand   Photoimpact   多媒体   图形图像

标准 网站致力的规范

Valid CSS!

无不良内容,无不良广告,无恶意代码

Valid XHTML 1.0 Transitional

creativecommons