在web应用中,难免和数据库打交道,对于返回的结果集,究竟该如何处理?
尤其是,当你的一个查询可能会返回数万条纪录的时候,你还能像某些骗钱骗精力的jsp垃圾书本上介绍的用rs.next()来处理么?
呵呵,我以前就是这么干的,直接传回resultset,在jsp中while(rs.next())循环中一个
一个的处理。
还有,返回结果的分页处理的问题。很多时候我们的web应用(或者其他)都是针对某一种数据库的(感觉商业应用绝大多数是oracle,业余的多是mysql,还敢用jdbc连接sqlserver的,估计是被m$养废了)。所以我常常会针对某些数据库的特性写一些专门的sql语句或者存储过程来确定返回结果集的大小,以实现分页处理(其实偶是数据库白痴,除了select/insert/update,其他的不知道!)。我以前就是用伪列来实现在oracle上处理记录结果集的分页的。
慢慢的,为了所谓的降低代码耦合度,我对查询结果集的代码进行了重构,于是稍微进步了一点,在某个querymanager之类的类中传出一个enumeration,里边的每个对象对应了数据库中的一条纪录。嘿嘿,居然也能凑合着对付500多人使用了。
可是,这也不是最好的办法,毕竟,如果真的返回了几万条纪录,这样的处理方法不但占内存,而且效率也不搞。
记得以前在bqlr.com中看到一篇关于“查询结果返回rs,还是集合”的讨论,答案是用iterator。
可是里边的代码很笼统,对于从未用过iterator模式的人来说,基本上没有什么可以模仿和参照的。
还好,我们有现成的,那就是jive。
看看jive中是怎么实现的。
(a)我们以forum.jsp这个页面为例,缺省的,每页显示15条thread,用户可以指定从第n条开始显示到n+page_size条。
代码如下:
resultfilter filter = new resultfilter();
filter.setstartindex(start); //从第start条thread开始
filter.setnumresults(range); //页面大小
// set the moderation level minimum
filter.setmoderationrangemin(forum.getmoderationminthreadvalue());
// more forum properties
int numthreads = forum.getthreadcount(filter);
int nummessages = forum.getmessagecount(filter);
// iterator of threads
forumthreaditerator threads = forum.threads(filter); //返回thread iterator,
// threadblock的length是400,从1~400(*注2)//嘿嘿,理解了上面几句代码先,然后来看这个iterator
long[]threadblock = getblock(query.tostring(), resultfilter.getstartindex());
int startindex = resultfilter.getstartindex();
int endindex;
// if number of results is set to inifinite, set endindex to the total
// number of threads in the forum.
if (resultfilter.getnumresults() == resultfilter.null_int) {
endindex = (int)getthreadcount(resultfilter);
}
else {
endindex = resultfilter.getnumresults() + startindex;
}
int blockid = startindex / block_size;
int blockstart = blockid * block_size;
con = connectionmanager.getconnection();
stmt = connectionmanager.createscrollablestatement(con);
// set the maximum number of rows to end at the end of this block.
connectionmanager.setmaxrows(stmt, block_size * (blockid+1));
resultset rs = stmt.executequery(query);
// grab block_size rows at a time.
connectionmanager.setfetchsize(rs, block_size); //一次最多取block_size条,也就是400条
// position the cursor right before the first row that we're insterested in.
connectionmanager.scrollresultset(rs, blockstart);// 滚动游标到blockstart
// keep reading results until the result set is exhausted or
// we come to the end of the block.
int count = 0;
while (rs.next() && count < block_size) {
objectlist.add(rs.getlong(1));
count++;
}
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 安全 模式 框架 测试 开源 游戏
Windows XP Windows 2000 Windows 2003 Windows Me Windows 9.x Linux UNIX 注册表 操作系统 服务器 应用服务器