jive中关于批量查询有两种实现方式:以ForumThreadBlockIterator为代表的实现方式和以DatabaseObjectIterator为代表的实现方式,在一个页面中含有少量数据时推荐使用后者,关于它的介绍前文已经提到,前者适合在数据量巨大、需要多页查询时使用。来看一下分页显示一个论坛中的主题时的代码
public ForumThreadIterator threads(ResultFilter resultFilter) {
String query = getThreadListSQL(resultFilter, false);
long [] threadBlock = getThreadBlock(query.toString(), resultFilter.getStartIndex());
int startIndex = resultFilter.getStartIndex();
int endIndex;
if (resultFilter.getNumResults() == ResultFilter.NULL_INT) {
endIndex = (int)getThreadCount(resultFilter);
}
else {
endIndex = resultFilter.getNumResults() + startIndex;
}
return new ForumThreadBlockIterator(threadBlock, query.toString(),
startIndex, endIndex, this.id, factory);
}
1. getThreadListSQL :获得查询语句SQL,通过该SQL,将返回所有符合条件的threadid的值
2. getThreadBlock:获得当前页面的ThreadID块(jive中把threadid按200个记录分成一块,每块中存放200个thread id,此种做法主要是为了缓存方便,块的缓存索引由查询块的SQL语句和块ID号组成),当前页面的thread id可能存在于一个thread块中,也可能跨多个thread块。所以,在ForumThreadBlockIterator的getElement中当要取得的threadid不在当前块中,必须得到下一个块。
3. 取得当前页面的开始和结束的记录号(在SQL中查询出来的所有记录中的排列序号)
4. 根据2、3得到一个页面的迭代器
读了彭晨阳的java实用系统关于jive论坛部分,容易混淆的是第二步所取得的Block并不是当前页面所有的Thread ID,而是按200记录分块所划的块的Thread ID。最后提到的ForumThreadBlockIterator是关于当前页的迭代器。书中把Block和用户访问的页混淆了,令人费解。
另外,在真正用户访问的过程中,threads用的是forumproxy的方法,返回的迭代器同样也加了权限控制了。