引用 http://www.blogjava.net/mintqzy/archive/2007/01/18/94694.html
本文是在参阅了http://ivanl.iteye.com/blog/24739基础上完成的
在看JPetStore的代码时,发现它的分页处理主要是通过返回PaginatedList对象来完成的。如:在CatalogService类中
publicPaginatedListgetProductListByCategory(StringcategoryId){
returnproductDao.getProductListByCategory(categoryId);
}
分页是操作数据库型系统常遇到的问题。分页实现方法很多,但效率的差异就很大了。iBatis是通过什么方式来实现这个分页的了。查看它的实现部分:
返回的PaginatedList实际上是个接口,实现这个接口的是PaginatedDataList类的对象,查看PaginatedDataList类发现,每次翻页的时候最后都会调用下面这段函数
privateListgetList(intidx,intlocalPageSize)throwsSQLException{
returnsqlMapExecutor.queryForList(statementName,parameterObject,(idx)*pageSize,localPageSize);
}
由于
publicinterfaceSqlMapClientextendsSqlMapExecutor,SqlMapTransactionManager{……}
所以实际的调用次序如下:
SqlMapClientImpl.queryForPaginatedList->SqlMapSessionImpl.queryForPaginatedList
->SqlMapExecutorDelegate.queryForPaginatedList->GeneralStatement.executeQueryForList
->GeneralStatment.executeQueryWithCallback->GeneralStatment.executeQueryWithCallback
->SqlExecutor.executeQuery->SqlExecutor.handleMultipleResults()->SqlExecutor.executeQuery->handleResults
分页处理的函数如下
privatevoidhandleResults(RequestScoperequest,ResultSetrs,intskipResults,intmaxResults,RowHandlerCallbackcallback)throwsSQLException{
try{
request.setResultSet(rs);
ResultMapresultMap=request.getResultMap();
if(resultMap!=null){
//SkipResults
if(rs.getType()!=ResultSet.TYPE_FORWARD_ONLY){
if(skipResults>0){
rs.absolute(skipResults);
}
}else{
for(inti=0;i<skipResults;i++){
if(!rs.next()){
return;
}
}
}
//GetResults
intresultsFetched=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);
}
}
由此可见,iBatis的分页主要依赖于jdbcdriver的如何实现以及是否支持rs.absolute(skipResults)。它并不是一个好的分页方式。它先要取出所有的符合条件的记录存入ResultSet对象,然后用absolute方法进行定位,来实现分页。当记录数较大(比如十万条)时,整体的查询速度将会变得很慢。
所以分页还是要考虑采用直接操作sql语句来完成。当然小批量的可以采用iBatis的分页模式。一般分页的sql语句与数据库的具体实现有关
mysql:
select*fromAlimitstartRow,endRow
oracle:
selectb.*from(selecta.*,rownumaslinenumfrom(select*fromA)awhererownum<=endRow)bwherelinenum>=startRow
Hibernate的Oracle分页采用的就是是拼凑RowNum的Sql语句来完成的。参考代码如下:
publicStringcreateOraclePagingSql(Stringsql,intpageIndex,intpageSize){
intm=pageIndex*pageSize;
intn=m+pageSize;
return"select*from(selectrow_.*,rownumrownum_from("+sql
+")row_whererownum<="+n
+")whererownum_>"+m;
}
综上,小批量(<2w)可以采用ibatis自带的分页类,大批量的还是直接操纵sql,当然也可以将这些sql自己进行封装,或在包中封装都可以。包封装的示例代码如下:
一个封装了分页功能的Oracle Package
createorreplacepackagebodyFMW_FY_HELPERis
PROCEDUREGET_DATA(pi_sqlinvarchar,pi_whichpageininteger,pi_rownumininteger,
po_cur_dataoutcur_DATA,po_allrownumoutinteger,pio_succeedinoutinteger)
as
v_cur_datacur_DATA;
v_cur_tempcur_TEMP;
v_tempinteger;
v_sqlvarchar(5000);
v_temp1integer;
v_temp2integer;
begin
pio_succeed:=1;
v_sql:='selectcount(''a'')from('||pi_sql||')';
executeimmediatev_sqlintov_temp;
po_allrownum:=ceil(v_temp/pi_rownum);
v_sql:='';
v_temp:=pi_whichpage*pi_rownum+1;
v_temp1:=(pi_whichpage-1)*pi_rownum+1;
v_temp2:=pi_whichpage*pi_rownum;
v_sql:='select*from(selectrownumasrn,t.*from('||pi_sql||')twhererownum<'||to_char(v_temp)||')wherernbetween'||to_char(v_temp1)||'and'||to_char(v_temp2);
openv_cur_dataforv_sql;
ifv_cur_data%notfound
then
pio_succeed:=-1;
return;
endif;
po_cur_DATA:=v_cur_data;
end;
分享到:
相关推荐
在IT行业中,分页是数据库查询的一个重要特性,特别是在数据量庞大的情况下,它能帮助...在 chap_ibatis 压缩包中,可能包含了相关的Ibatis分页源码示例,你可以进一步研究其中的细节,加深对Ibatis分页机制的理解。
- **数据访问对象(DAO)模式**:深入研究iBATIS如何支持DAO模式,简化数据访问逻辑,实现业务逻辑与数据访问的分离。 - **扩展iBATIS**:学习如何自定义插件,扩展iBATIS的功能,满足特定的业务需求。 ### iBATIS...
深入研究iBatis源码有助于理解其内部工作原理,包括如何解析XML配置文件,如何执行SQL语句,以及如何进行结果映射。源码分析可以帮助开发者更好地定制和优化自己的应用。 六、iBatis实践项目 通过实践项目,可以...
7. **插件机制**:介绍如何编写和使用Ibatis的插件,如PageHelper分页插件。 8. **最佳实践**:提供在实际项目中使用Ibatis的建议,如合理规划Mapper接口,避免SQL注入等。 【IbatisStudy项目结构及内容】 在提供...
SSH2+IBATIS框架是Java开发中常用的一套企业级应用开发框架...开发者可以通过研究这个示例,了解各个组件如何协同工作,以及如何实现分页查询。这有助于快速搭建企业级的Java Web应用,并为后续的开发工作提供基础。
此外,iBATIS可以统一编码风格,减少开发成本,开发者可以更专注于业务逻辑的实现,而无需过多关注分页、连接池、主键生成等基础操作。 iBATIS对SQL的简单封装,类似于在JDBC之上增加了一个外壳,它简化了JDBC的...
描述中提到的“分页分的挺完美的”,这涉及到Struts2或iBatis中的分页实现。在Struts2中,可以通过拦截器或者自定义插件来实现分页功能,而在iBatis中,可以通过编写动态SQL来实现分页查询。描述还指出“但是删除有...
- **分页查询**:讲解如何实现分页查询功能。 - **多表查询**:介绍处理多表联接查询的方法。 #### 2.5 事务管理 - **事务概念**:解释事务的基本原理及其在iBATIS中的应用。 - **配置方法**:指导如何配置iBATIS以...
10. **插件扩展**:Ibatis允许开发者创建自定义插件,如PageHelper分页插件,以实现特定功能或优化性能。 11. **最佳实践**:在实际应用中,应合理规划Mapper接口和XML文件,避免过度复杂的SQL,同时注意优化事务...
在压缩包文件"iBatisResearch"中,可能包含了作者对iBATIS 3的研究文档、示例代码或者测试用例,这些内容可以帮助读者更直观地了解和掌握iBATIS 3的使用方法。通过阅读和实践这些材料,可以进一步巩固理论知识,提升...
为了满足更复杂的查询需求,iBATIS提供了一系列高级查询技术,如动态SQL、分页查询等。动态SQL允许开发者根据运行时条件动态生成SQL语句,极大地提高了SQL语句的灵活性和复用性。 **2.5 事务管理** iBATIS支持多种...
【酒店客房管理系统(毕业设计) struts + spring + ...对于初学者来说,这个项目提供了学习Java Web开发和企业级框架的实践经验,通过研究源代码和数据库设计,可以深入了解MVC模式、数据库交互以及业务逻辑的实现。
### 基于Ext的JavaEE快速开发研究 #### 摘要 本文重点探讨了如何将Ext框架与JavaEE中的多个开源框架整合,形成一套从前端到后端的高效开发流程。首先介绍了Ext框架的基本特性和优势,然后讨论了Ext与Struts2的整合...
本书有丰富的附录部,在附录中讲述了Hibernate常用的映射配置,Hibernate工具、XDoclet模板配置以及Hibernate的益友iBatis用法,还以卡片的形式列出了本书中所用的工具及软件,附录最后一部分是“快速启动代码”,供...
9. **异常处理**:MyBatis 提供了统一的异常处理机制,如`org.apache.ibatis.exceptions.PersistenceException`,便于捕获和处理数据库操作中的错误。 10. **最佳实践**:在压缩包中,我们可能还能发现一些最佳实践...
通过对源码的分析,开发者可以了解如何使用Struts2的注解来定义Action,如何处理表单提交,如何实现分页和搜索功能,以及如何进行错误和异常处理。此外,通过查看数据库设计,还可以了解到如何优化数据模型以满足...
6. **插件化设计**:JFinal 采用插件化设计,开发者可以根据需求选择使用不同的插件,如上传插件、缓存插件、分页插件等,这些插件可以快速扩展功能,而不会影响核心代码。 7. **模板引擎支持**:JFinal 支持 ...
在Java中,我们可以定义一个接口,该接口继承自`org.apache.ibatis.annotations.Mapper`,并包含SQL查询方法。同时,为每个接口创建对应的XML映射文件,用于编写SQL语句和结果映射。Spring Boot会通过`...
- **项目二**:员工信息录入系统,使用Struts框架,实现了信息录入、修改、验证等功能,进行了分页等开源项目的实践研究。 ### 自我评价与职业态度 自我评价部分反映了求职者的个人特质和职业态度,这在招聘过程中...