板桥先生您好
就数据库查询之后是返回collection 还是返回iterator,按照您的说法返回collection会浪费内存,可是我觉得返回collection不一定会浪费内存,按照您的做法返回ResultSet的iterator,相当是在前后台传递数据库记录的指针了,这里有个问题,要使传递的指针有效那么必须保证在遍历记录的时候,ResultSet对象一直有效,也就是ResultSet对象占用的内存不可以释放,因此就内存耗费来说,返回collection和iterator是没有区别的,前者把ResultSet的记录转移到collection对象中,不错collection是要开辟一块内存,但是记录转移到collection中后,ResultSet对象就可以释放掉了,总的内存使用并没有增加。
不知道我的看法是否正确,欢迎道友们指正。
〉不错collection是要开辟一块内存,但是记录转移到collection中后,ResultSet对象就可以释放掉了,总的内存使用并没有增加。
同意。
在此之前讨论过的呀,在Connection关闭的时候ResultSet会随之关闭,所以不能使用ResultSet缓存查询结果。可能跟JDBC驱动有关系。不知道谁遇到这样的jdbc驱动,能够实现Connection和ResultSet相互独立?
是呀! 我也这样觉得的collection是要开辟一块内存,但同时也可以将ResultSet对象释放掉,并且对记录对象的遍历的效率也应该是在同一等级上的(具体的实现我没有研究过)!
Think resultset as a forward only stream or two way stream, while using all default jdk collection implementations need to be fully loaded so it consumes more memory.
But you can have a incremental collection( Websphere did it in WAS5), which is a wrapper around the underlying resultset.

-Jevang

to jevang
>But you can have a incremental collection( Websphere did it in WAS5), which is a wrapper around the underlying resultset.

"wrapper around the underlying resultset"是否说这时候resultset所属于的connection可以close?resultset也可以close?

Hi Blue,
Indeed that's going to happen, but since there is no notion "close" for a collection, you probably ends up with calling rs.close() from Collection.clear() or iterator.remove()
板桥是对的,你关了CONNECTION一样可以访问,你随便试一下就知道了,我以前也是这么用的

关于IERTATOR板桥是高

作用只有一个,封装

不错,非常好啊

hello iamwls,

我又尝试了一下,在oracle中。代码段大概是这样:
Class.forName("oracle driver");
Connection conn = DriverManager.getConnection(...);
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("select * from foo");
conn.close();
while(rs.next()){
print out;
}
运行的结果是rs.next()时出错,
"java.sql.SQLException:关闭的连接:next"

我记得原来在sybase上也是这个结果。而且sybase更厉害,报告的错误是"resultset被关闭"

我现在不能确信的是:是否有某些JDBC Driver的实现方式是"可以关闭CONNECTION后可以访问resultset",或者是因为你使用的是weblogic中的datasource,所以当conn.close()时该connection只是返回到pool中,而没有真正close。

我记得在weblogic中使用connection pool的时候,oracle似乎可以实现你说的这种方式,而sybase则不行。不知道你的应用情况是怎么样的.

所以我认为至少某些JDBC Driver是不能"关闭connection后还能使用resultset"的,从而也说明了jdbc driver规范中没有规定"close connection后还可以使用resultset"。

up
faint.
stmt.close()后居然还去使用ResultSet,绝对非法。
有些人碰巧能用,只不过GC还没有把垃圾清理干净。
请看java api的关于ResultSet的文档:
....
A ResultSet object is automatically closed when the Statement object that generated it is closed, re-executed, or used to retrieve the next result from a sequence of multiple results.
.....
初来杂到,多多交流

我认为 浆糊 的担心是有必要的.
We should consider when we should close the DB connection.

Also, I think transmiting Data Package one time on distributed system is better than Iterator which will always disturbs the network traffic.

I wrote the following codes.
Throught these codes, Banq doesn't need to worry this situation: If DB table structure changes, then we should change the JSP presention codes.

//package recordset as vector,because vector is easy to operate
private Vector packageRecordSetAsVector(ResultSet rs) throws SQLException
{
if (rs == null) return null;
Vector V = new Vector();
ResultSetMetaData rsmd = rs.getMetaData();// record column name
int numColumn = rsmd.getColumnCount();
Vector colV=new Vector();
for(int j=1;j colV.addElement(rsmd.getColumnName(j));
}
V.add(colV);
int xx = 0;
while(rs.next()){
Hashtable Ht = new Hashtable();
for(int i=1;i if (rs.getString(i)==null){
Ht.put(rsmd.getColumnName(i),"");
}else{
Ht.put(rsmd.getColumnName(i),rs.getString(i));
}
}
V.addElement(Ht);
xx++;
}
return V;
}

想法不错,可是忽略了一些问题。
1)数据量大的情况下,如何控制DB连接数;
2)如果用COLLECTION可以做CACHE,而ITERATOR不行;
3)不适用于分布式应用,比如客户端是RMI调用。
我返回的是值对象,页面使用jstl处理。
对于关闭CONNECT后仍可以操作RS,我做过实验,低版本JDBC的MYSQL上可以,ORACLE上不可以这样操作。

不过我从来不做将RS直接封装成COLLECTION,或ITERATOR的操作。
而是根据具体的业务对象进行对象的实例化,再将一个个对象放入到ARRAYLIST中返回,不知这有什么问题