我初来这个论坛,觉得大家都很热情。
看了大家发言,我也来说两句:

1。首先关于JDBC的调用的问题,RS,ST,CONN的关闭是需要一定顺序的,
SQLUtil.safelyCloseResultSet(rs);
SQLUtil.safelyCloseStatement(pstQuery);
SQLUtil.safelyCloseConnection(connection);

如果你关闭ST和CONN,而继续使用RS的话,可能在某些平台(JVM)某些JDBC driver上能运行通过,但
不保证都能在所有java vm上通过。应为你违反了java spec.我想这种方式是应该不提倡的。

2。关于Jive的数据库调用的问题(iterator)
因为jive是个bbs,所以jive中所有的问题都采用id的分配方式来确定一个概念(祥见数据库设计)。
id的概念在很大程度上能够解决bbs的需求问题。Jive返回的iterator其实是通过装载数据库某个实体的
全部PK(即id)进行定位的。load实体的时候是通过objectfactoy装载实体的(里面就有cache)了。
其实这里有两个问题:
a。实体对象的规模。
b。实体对象排序。
如果实体对象的规模过大,即不是bbs系统了。jive的方式会crash的。因为jive装载了所有的PK
jive不能返回对象级排序(根据实体的某个属性)的实体iterator

但jive对bbs来说,这种实施方式已经是够了。

3.关于ResultSetPage的概念。
其实这个就是为了解决实体对象规模的问题。采用page的概念划分RS.减少数据返回大小(用RS的next功能)。


4.查询数据库后是返回java.sql.ResultSet还是返回Collection.
要是你在Collection里面依然采用直接包装ResultSet的方式,在性能上没有丝毫好处。唯一的好处是
对jsp程序员屏蔽了RS的访问。
Collection需要对java.sql.ResultSet的数据进行page的包装。才有性能上的效果。

若发送SQL语句后,程序只从数据库中取得查询结果的ID号;然后,程序把ID号保存到EJB的一个Vector中;网页读取结果时(get),程序查找数据并显示。
如:默认每页显示的数据为10个,现网页要显示第2页的内容,那么,EJB就从ID号的Vector里找到第21到30的ID,然后再用Select * from table where id=[ID]来查询数据;最后把这些查到的数据构造成Vector返回给网页。这样的做法有什么利弊?恳请各位大侠指教。
一个问题讨论了整整一年,banq都懒得再回了,真有意思!

如果用Hibernate,框架已经做了足够的封装,Session.find()返回包含所有记录的List,而Session.iterator()返回Iterator,而且你遍历的结果总是JavaBean,而且你看不到ResultSet,真好!

可是要整个数据结果集遍历啊。 就象我们看一本书一样,我们都是先翻到一定的页数然后才开始阅读,为什么每次都要从头到尾翻阅一遍?我的做法是把从头到尾翻转化成要翻哪页就翻哪页,这种想法没有什么不对呀?可是我是刚踏入JAVA编程的菜鸟,真的不知道会有什么弊端,恳请各位大侠指教啊。
这种方法不成立,以下问题如何解决?
1.id号不连续。
2.不按id号排序,且排序字段没有唯一性约束,比如日期。
哦,这样的话是不是就相当于是一个Entity Bean??
1、Vector中保存的id号本来就是不连续的。2、若没有id字段的还真的不行。
Hi sliuhao!
1)我认为如果关闭了st和conn继续调用rs。next,除非数据都是存储在rs中才不会出错(取决fetch size),否则,因为rs必须再次访问db,而连接都已经关闭。但是我发现mysql,hsqldb等开源的jdbc driver都是忽略了setFetchSize(),总是在查询中装入所有数据。
2)即使装入所有id,我觉得问题也不会很大吧,对于long id百万数据也不过几M,当然如果并发量大就不知道了(也许常用的可以cache了)。如果好的driver应当是懒装入的。不过排序完全可以在sql中实现,很大的集合全部导入内存排序太不可思议了。
4)一般的应用我觉得瓶颈不在这点优化,也许选个好driver和db就解决问题了
另外jdbc2+的rowset也是包装rs
欢迎指正
讨论了这么多,也没什么定论,看来这个东西很难有所定论 :)

我的意见是取一个较大的collection,比如要显示15个,则可取100个在缓存中。链接断开
显示之前可进行过滤等操作,数量不够时,透明的重新连接数据库取下100个

我认为connection关闭后resultset是不可用的,按照jdbc规范,statement关闭就会导致resultset的关闭,以上各位遇到connection关闭后resultset仍可使用的问题,不知是否使用了连接池,如果使用连接池的话,是因为connection并未真正关闭,所以才会出现resultset仍可使用的现象
我的意见是如果数据量不是太大的话完全可以使用ArrayList,实现方便,效率高,接口统一,即使使用iterator的话,每个对象依然会被创建,jvm是否会及时释放每个内存依然是个问题,如果不能在对象使用完只后释放内存用iterator也无法达到节约内存的目的,反而牺牲了性能。
如果数据量很大的情况就必须考虑更复杂的实现,例如jive的实现,简单的使用iterator是没有多大作用的
> 我认为connection关闭后resultset是不可用的,按照jdbc规?> ,statement关闭就会导致resultset的关闭,以上各位遇到co
> nection关闭后resultset仍可使用的问题,不知是否使用了连
> 映兀绻褂昧映氐幕埃且蛭connection并未真正关闭?> 所以才会出现resultset仍可使用的现象

这个说的有理。
关闭resultset继续使用是个原则性的错误

虽然这个讨论是激烈的,但这个讨论也是罪恶的。
我曾经咨询过Bea和Sun的咨询师关于connection关闭的问题,答案是一致的,哪里使用,哪里关闭,在connection关闭之前,connection对象产生的statement和resultset都要关闭。

所以,很简单,凡是把ResultSet作为方法参数传来传去的程序我是不看的,凡是写这样的程序的人,如果够的着我是要批的。

希望新手们切记:永远不要把statement和resultset传来传去的使用。
虽然你现在不理解,总有一天,你也会这样对新人们说。

说的好!
说来说去, 好像问题又回到了关于connection和rs的问题.
如果不使用连接池机制, 关闭connection, 必然关闭resultset!
如果使用连接池, 所谓的关闭connection, 其实是将连接返回给了连接池,
连接对象依然存在, 所以这实际上不叫关闭!!!!!

所以说, 这其实是一个简单的问题.

不过这个讨论倒是有助于大家的理解!!

另外: 无论是查询一条记录还是多条记录, 都应该采用值对象(value object)或者值对象集合的形式传给客户端, 这样可以最大程度的减少网络负载. 试问,你将一个结果集传给客户端, 每次调用都要访问一次后台, 这将是多大的开销??

Bang是性能至上论者,我比较怕和性能至上论者讨论问题,呵呵。
因为我拿不出大多数情况下我们根本不需要考虑性能的证据。
现在http://gceclub.sun.com.cn/NASApp/sme/controller/sublearning?cat_level=1&cat_id=01
有Sun的在线讲堂,里面有一篇关于java性能的讲座。主要是一些原则性问题。大家看看:
mellonK6a3oWL07e.jpg
我一直认为,在不犯原则性错误导致性能下降的情况下,尽管写你的程序好了,不要老惦记性能,在分析设计阶段扭曲一些原则而求性能,最后影响了设计的灵活性、可扩展性,可维护性往往悔不当初,得不偿失。