锁定老帖子 主题:ibatis分页源码分析
精华帖 (0) :: 良好帖 (1) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2006-08-25
实现翻页,刚才测试了一下PaginatedList,在1-2w行数据的时候还可以工作,但是在一个30w行的表里翻页,一次select用了363.031second 忍不住看了一下源,发现ibatis的分页依赖于数据库的jdbcDriver. 调用次序如下SqlMapClientImpl.queryForPaginatedList->SqlMapSessionImpl.queryForPaginatedList ->SqlMapExecutorDelegate.queryForPaginatedList->GeneralStatement.executeQueryForList ->GeneralStatment.executeQueryWithCallback->GeneralStatment.executeQueryWithCallback ->SqlExecutor.executeQuery->SqlExecutor.handleMultipleResults() 分页处理的函数如下 private void handleResults(RequestScope request, ResultSet rs, int skipResults, int maxResults, RowHandlerCallback callback); throws SQLException { try { request.setResultSet(rs);; ResultMap resultMap = request.getResultMap();; if (resultMap != null); { // Skip Results if (rs.getType(); != ResultSet.TYPE_FORWARD_ONLY); { if (skipResults > 0); { rs.absolute(skipResults);; } } else { for (int i = 0; i < skipResults; i++); { if (!rs.next();); { return; } } } // Get Results int resultsFetched = 0; while ((maxResults == SqlExecutor.NO_MAXIMUM_RESULTS || resultsFetched < maxResults); && rs.next();); { Object[] columnValues = resultMap.resolveSubMap(request, rs);.getResults(request, rs);; callback.handleResultObject(request, columnValues, rs);; resultsFetched++; } } } finally { request.setResultSet(null);; } } 返回的PaginatedList实际上是PaginatedDataList类的对象,每次翻页的时候最后都会调用 private List getList(int idx, int localPageSize); throws SQLException { return sqlMapExecutor.queryForList(statementName, parameterObject, (idx); * pageSize, localPageSize);; } 这个方法,可见ibatis的分页机制要看jdbcDriver如何实现以及是否支持rs.absolute(skipResults)。 这种实现肯定不如数据库自己支持的分页方式来的快,一旦碰到数据量大的表,马上会死翘翘。 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2006-08-28
是呀。。同意你的观点,其实,我一直觉得物理翻页是最好的,ibatis不支持物理翻页,这点比较费解。我想把物理翻页封装起来,但感觉不是特别好做。坛子里搞ibatis的人好象不是很多呀。。看来,这个项目也不是特别活跃。
|
|
返回顶楼 | |
发表时间:2006-09-13
SqlMapClientImpl , SqlMapSessionImpl有什么不同???郁闷中
|
|
返回顶楼 | |
发表时间:2006-09-13
分页工具,最好还是自己封装成类!
Ibatis这个还不能满足大多数应用! 比如,数字分页,上下分页,跳转等等! 不可能将这些代码重复得写! 且分页让SQL控制,是较好的性能表现! mysql: select * from A limit startRow,endRow oracle: select b.* from (select a.*,rownum as linenum from (select * from A) a where rownum <= endRow) b where linenum >= startRow |
|
返回顶楼 | |
发表时间:2006-09-13
而且这个东西要写order by的 否则翻一翻数据就会乱掉
|
|
返回顶楼 | |
发表时间:2006-09-13
总之不要用,除非你的数据量很小
|
|
返回顶楼 | |
发表时间:2006-09-13
直接用SQL实现可以了,针对不同数据库的都有,GOOGLE一下?
|
|
返回顶楼 | |
发表时间:2006-09-14
Ibatis不是物理分页,不要用queryForPaginatedList,性能不好。他也没有针对各种数据库做实现。这个自己实现就好了,很简单的事情
|
|
返回顶楼 | |
发表时间:2006-09-18
LZ的性能问题主要是因为你的数据库不支持ResultSet的absolute方法吧?若支持这个方法这个性能问题应该不存在的。
引用 for (int i = 0; i < skipResults; i++) {
if (!rs.next()) { return; } } 应该是这部分代码是性能瓶颈。 queryForPaginatedList()方法其实很好用,足够实现所有的分页功能,包括跳转、页面单击排序、页面指定容量等特性,只需加一个包装类即可,使用数据库的分页功能,虽然性能最好,但要实现完善的分页特性,包装类也要花大量的时间编写和测试的。 除去旧版本的数据库,目前的jdbc Driver极少不支持ResultSet的absolute方法,我做过的一个项目是MySql4.1,10W数据测试,分页速度很快,绝对没有360秒级的恐怖问题。 |
|
返回顶楼 | |
发表时间:2006-09-18
孤立数据库谈ibatis的翻页问题是不完善的,至少要对这三个数据库进行测试mysql,postgresql,oracle,同时还要确定版本。
|
|
返回顶楼 | |