最近在学习iBatis的分页功能,iBatis默认的分页是采用游标滚动的方式来实现的,这种方式在大数据量的情况下便会OOM了,因此一般都采用手写分页SQL语句使用数据库物理分页方式实现,参考了网上很多网友所写的如何实现像hibernate一样使用方言的方式来实现分页功能,基本上千篇一律都是继承com.ibatis.sqlmap.engine.execution.SqlExecutor类然后在spring中进行注入等等,操作复杂编码甚多,方法不可取。
另外还有些是修改iBatis的jar包来实现,本人觉得这种方法更不可取。
基于网友们的思想,自己实现了另一种方法,不用修改源码,不用在spring中做任何配置即可实现物理分页功能:
条件
1、JVM类的加载是通过Class.forName(String cls)来实现,根据这个原理可以自己写一个与com.ibatis.sqlmap.engine.execution.SqlExecutor同名类;
2、java web类的加载顺序是:首先是web容器的相关类与jar包,然后是web工程下面WEB-INF/classes/下的所有类,最后才是WEB-INF/lib下的所有jar包;
有了以上的先决条件就好办了,可以在你的项目src目录下建包com.ibatis.sqlmap.engine.execution,然后在此包下建类SqlExecutor,然后把iBatis包下的这个类的源码复制进来后做小小改动,原来的executeQuery方法改成私有、换名,换成什么名称随便,然后新建一个公有的executeQuery方法,分页功能就在这个方法体内实现;
这样一来,web容器首会找到WEB-INF/classes下的com.ibatis.sqlmap.engine.execution.SqlExecutor这个类,因而会忽略掉在ibatis包中的这个类,即实现了自定义的分页功能,又不用去破坏ibatis的包;
还有一点,也可以将自定义的这个类打成jar包放到lib中去,不过这时就要注意了,jar包的名称一定要在ibatis包的名称之前,也就是说ibatis-2.3.4.726.jar,那么这个jar就可以写成ibatis-2.3.4.725.jar,或者字母在ibatis这几个字母之前,这样才能正确加载自己写的那个类。
贴上代码:
SqlExecutor.java
Dialect.java
基于网友们的思想,自己实现了另一种方法,不用修改源码,不用在spring中做任何配置即可实现物理分页功能:
条件
1、JVM类的加载是通过Class.forName(String cls)来实现,根据这个原理可以自己写一个与com.ibatis.sqlmap.engine.execution.SqlExecutor同名类;
2、java web类的加载顺序是:首先是web容器的相关类与jar包,然后是web工程下面WEB-INF/classes/下的所有类,最后才是WEB-INF/lib下的所有jar包;
有了以上的先决条件就好办了,可以在你的项目src目录下建包com.ibatis.sqlmap.engine.execution,然后在此包下建类SqlExecutor,然后把iBatis包下的这个类的源码复制进来后做小小改动,原来的executeQuery方法改成私有、换名,换成什么名称随便,然后新建一个公有的executeQuery方法,分页功能就在这个方法体内实现;
这样一来,web容器首会找到WEB-INF/classes下的com.ibatis.sqlmap.engine.execution.SqlExecutor这个类,因而会忽略掉在ibatis包中的这个类,即实现了自定义的分页功能,又不用去破坏ibatis的包;
还有一点,也可以将自定义的这个类打成jar包放到lib中去,不过这时就要注意了,jar包的名称一定要在ibatis包的名称之前,也就是说ibatis-2.3.4.726.jar,那么这个jar就可以写成ibatis-2.3.4.725.jar,或者字母在ibatis这几个字母之前,这样才能正确加载自己写的那个类。
贴上代码:
SqlExecutor.java
- /*
- *Copyright2004ClintonBegin
- *
- *LicensedundertheApacheLicense,Version2.0(the"License");
- *youmaynotusethisfileexceptincompliancewiththeLicense.
- *YoumayobtainacopyoftheLicenseat
- *
- *http://www.apache.org/licenses/LICENSE-2.0
- *
- *Unlessrequiredbyapplicablelaworagreedtoinwriting,software
- *distributedundertheLicenseisdistributedonan"ASIS"BASIS,
- *WITHOUTWARRANTIESORCONDITIONSOFANYKIND,eitherexpressorimplied.
- *SeetheLicenseforthespecificlanguagegoverningpermissionsand
- *limitationsundertheLicense.
- */
- packagecom.ibatis.sqlmap.engine.execution;
- importjava.sql.BatchUpdateException;
- importjava.sql.CallableStatement;
- importjava.sql.Connection;
- importjava.sql.PreparedStatement;
- importjava.sql.ResultSet;
- importjava.sql.SQLException;
- importjava.sql.Statement;
- importjava.sql.Types;
- importjava.util.ArrayList;
- importjava.util.List;
- importorg.apache.commons.logging.Log;
- importorg.apache.commons.logging.LogFactory;
- importcom.ibatis.sqlmap.engine.impl.SqlMapClientImpl;
- importcom.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate;
- importcom.ibatis.sqlmap.engine.mapping.parameter.ParameterMap;
- importcom.ibatis.sqlmap.engine.mapping.parameter.ParameterMapping;
- importcom.ibatis.sqlmap.engine.mapping.result.ResultMap;
- importcom.ibatis.sqlmap.engine.mapping.result.ResultObjectFactoryUtil;
- importcom.ibatis.sqlmap.engine.mapping.statement.DefaultRowHandler;
- importcom.ibatis.sqlmap.engine.mapping.statement.MappedStatement;
- importcom.ibatis.sqlmap.engine.mapping.statement.RowHandlerCallback;
- importcom.ibatis.sqlmap.engine.scope.ErrorContext;
- importcom.ibatis.sqlmap.engine.scope.SessionScope;
- importcom.ibatis.sqlmap.engine.scope.StatementScope;
- /**
- *ClassresponsibleforexecutingtheSQL
- */
- @SuppressWarnings("unchecked")
- publicclassSqlExecutor{
- privatestaticfinalLoglog=LogFactory.getLog(SqlExecutor.class);
- //
- //Constants
- //
- /**
- *Constanttoletusknownottoskipanything
- */
- publicstaticfinalintNO_SKIPPED_RESULTS=0;
- /**
- *Constanttoletusknowtoincludeallrecords
- */
- publicstaticfinalintNO_MAXIMUM_RESULTS=-999999;
- publicSqlExecutor(){
- log.info("Customclass'SqlExecutor'Initialization");
- }
- //
- //PublicMethods
- //
- /**
- *Executeanupdate
- *
- *@paramstatementScope
- *-therequestscope
- *@paramconn
- *-thedatabaseconnection
- *@paramsql
- *-thesqlstatementtoexecute
- *@paramparameters
- *-theparametersforthesqlstatement
- *@return-thenumberofrecordschanged
- *@throwsSQLException
- *-iftheupdatefails
- */
- publicintexecuteUpdate(StatementScopestatementScope,Connectionconn,
- Stringsql,Object[]parameters)throwsSQLException{
- ErrorContexterrorContext=statementScope.getErrorContext();
- errorContext.setActivity("executingupdate");
- errorContext.setObjectId(sql);
- PreparedStatementps=null;
- setupResultObjectFactory(statementScope);
- introws=0;
- try{
- errorContext
- .setMoreInfo("ChecktheSQLStatement(preparationfailed).");
- ps=prepareStatement(statementScope.getSession(),conn,sql);
- setStatementTimeout(statementScope.getStatement(),ps);
- errorContext
- .setMoreInfo("Checktheparameters(setparametersfailed).");
- statementScope.getParameterMap().setParameters(statementScope,ps,
- parameters);
- errorContext.setMoreInfo("Checkthestatement(updatefailed).");
- ps.execute();
- rows=ps.getUpdateCount();
- }finally{
- closeStatement(statementScope.getSession(),ps);
- }
- returnrows;
- }
- /**
- *Addsastatementtoabatch
- *
- *@paramstatementScope
- *-therequestscope
- *@paramconn
- *-thedatabaseconnection
- *@paramsql
- *-thesqlstatement
- *@paramparameters
- *-theparametersforthestatement
- *@throwsSQLException
- *-ifthestatementfails
- */
- publicvoidaddBatch(StatementScopestatementScope,Connectionconn,
- Stringsql,Object[]parameters)throwsSQLException{
- Batchbatch=(Batch)statementScope.getSession().getBatch();
- if(batch==null){
- batch=newBatch();
- statementScope.getSession().setBatch(batch);
- }
- batch.addBatch(statementScope,conn,sql,parameters);
- }
- /**
- *Executeabatchofstatements
- *
- *@paramsessionScope
- *-thesessionscope
- *@return-thenumberofrowsimpactedbythebatch
- *@throwsSQLException
- *-ifastatementfails
- */
- publicintexecuteBatch(SessionScopesessionScope)throwsSQLException{
- introws=0;
- Batchbatch=(Batch)sessionScope.getBatch();
- if(batch!=null){
- try{
- rows=batch.executeBatch();
- }finally{
- batch.cleanupBatch(sessionScope);
- }
- }
- returnrows;
- }
- /**
- *Executeabatchofstatements
- *
- *@paramsessionScope
- *-thesessionscope
- *@return-aListofBatchResultobjects(maybenullifnobatchhasbeen
- *initiated).TherewillbeoneBatchResultobjectinthelistfor
- *eachsub-batchexecuted
- *@throwsSQLException
- *ifadatabaseaccesserroroccurs,orthedrivedoesnot
- *supportbatchstatements
- *@throwsBatchException
- *ifthedriverthrowsBatchUpdateException
- */
- publicListexecuteBatchDetailed(SessionScopesessionScope)
- throwsSQLException,BatchException{
- Listanswer=null;
- Batchbatch=(Batch)sessionScope.getBatch();
- if(batch!=null){
- try{
- answer=batch.executeBatchDetailed();
- }finally{
- batch.cleanupBatch(sessionScope);
- }
- }
- returnanswer;
- }
- /**
- *Longformofthemethodtoexecuteaquery
- *
- *@paramstatementScope
- *-therequestscope
- *@paramconn
- *-thedatabaseconnection
- *@paramsql
- *-theSQLstatementtoexecute
- *@paramparameters
- *-theparametersforthestatement
- *@paramskipResults
- *-thenumberofresultstoskip
- *@parammaxResults
- *-themaximumnumberofresultstoreturn
- *@paramcallback
- *-therowhandlerforthequery
- *@throwsSQLException
- *-ifthequeryfails
- */
- //-------------------------------分页代码重写(start)------------------------------------//
- //重写executeQuery方法,首先判断是否分页查询,分页查询先将分页SQL语句构建,然后执行iBatis默认的查询
- publicvoidexecuteQuery(StatementScopestatementScope,Connectionconn,
- Stringsql,Object[]parameters,intskipResults,intmaxResults,
- RowHandlerCallbackcallback)throwsSQLException{
- //取数据库产品名称
- StringdbName=conn.getMetaData().getDatabaseProductName();
- intlen=sql.length();
- //判断是否分页
- if((skipResults!=NO_SKIPPED_RESULTS||maxResults!=NO_MAXIMUM_RESULTS)){
- //根据数据库产品名称取对应的分页SQL语句
- sql=Dialect.getLimitString(dbName,sql,skipResults,maxResults);
- //分页语句是否存在
- if(sql.length()!=len){
- skipResults=NO_SKIPPED_RESULTS;
- maxResults=NO_MAXIMUM_RESULTS;
- }
- }
- iBatisExecuteQuery(statementScope,conn,sql,parameters,skipResults,
- maxResults,callback);
- }
- //iBatis包中默认的executeQuery方法
- privatevoidiBatisExecuteQuery(StatementScopestatementScope,
- Connectionconn,Stringsql,Object[]parameters,intskipResults,
- intmaxResults,RowHandlerCallbackcallback)throwsSQLException{
- ErrorContexterrorContext=statementScope.getErrorContext();
- errorContext.setActivity("executingquery");
- errorContext.setObjectId(sql);
- PreparedStatementps=null;
- ResultSetrs=null;
- setupResultObjectFactory(statementScope);
- try{
- errorContext
- .setMoreInfo("ChecktheSQLStatement(preparationfailed).");
- IntegerrsType=statementScope.getStatement().getResultSetType();
- if(rsType!=null){
- ps=prepareStatement(statementScope.getSession(),conn,sql,
- rsType);
- }else{
- ps=prepareStatement(statementScope.getSession(),conn,sql);
- }
- setStatementTimeout(statementScope.getStatement(),ps);
- IntegerfetchSize=statementScope.getStatement().getFetchSize();
- if(fetchSize!=null){
- ps.setFetchSize(fetchSize.intValue());
- }
- errorContext
- .setMoreInfo("Checktheparameters(setparametersfailed).");
- statementScope.getParameterMap().setParameters(statementScope,ps,
- parameters);
- errorContext.setMoreInfo("Checkthestatement(queryfailed).");
- ps.execute();
- errorContext
- .setMoreInfo("Checktheresults(failedtoretrieveresults).");
- //BeginResultSetHandling
- rs=handleMultipleResults(ps,statementScope,skipResults,
- maxResults,callback);
- //EndResultSetHandling
- }finally{
- try{
- closeResultSet(rs);
- }finally{
- closeStatement(statementScope.getSession(),ps);
- }
- }
- }
- //--------------------分页代码重写(end)-------------------------------------//
- /**
- *Executeastoredprocedurethatupdatesdata
- *
- *@paramstatementScope
- *-therequestscope
- *@paramconn
- *-thedatabaseconnection
- *@paramsql
- *-theSQLtocalltheprocedure
- *@paramparameters
- *-theparametersfortheprocedure
- *@return-therowsimpactedbytheprocedure
- *@throwsSQLException
- *-iftheprocedurefails
- */
- publicintexecuteUpdateProcedure(StatementScopestatementScope,
- Connectionconn,Stringsql,Object[]parameters)
- throwsSQLException{
- ErrorContexterrorContext=statementScope.getErrorContext();
- errorContext.setActivity("executingupdateprocedure");
- errorContext.setObjectId(sql);
- CallableStatementcs=null;
- setupResultObjectFactory(statementScope);
- introws=0;
- try{
- errorContext
- .setMoreInfo("ChecktheSQLStatement(preparationfailed).");
- cs=prepareCall(statementScope.getSession(),conn,sql);
- setStatementTimeout(statementScope.getStatement(),cs);
- ParameterMapparameterMap=statementScope.getParameterMap();
- ParameterMapping[]mappings=parameterMap.getParameterMappings();
- errorContext
- .setMoreInfo("Checktheoutputparameters(registeroutputparametersfailed).");
- registerOutputParameters(cs,mappings);
- errorContext
- .setMoreInfo("Checktheparameters(setparametersfailed).");
- parameterMap.setParameters(statementScope,cs,parameters);
- errorContext
- .setMoreInfo("Checkthestatement(updateprocedurefailed).");
- cs.execute();
- rows=cs.getUpdateCount();
- errorContext
- .setMoreInfo("Checktheoutputparameters(retrievalofoutputparametersfailed).");
- retrieveOutputParameters(statementScope,cs,mappings,parameters,
- null);
- }finally{
- closeStatement(statementScope.getSession(),cs);
- }
- returnrows;
- }
- /**
- *Executeastoredprocedure
- *
- *@paramstatementScope
- *-therequestscope
- *@paramconn
- *-thedatabaseconnection
- *@paramsql
- *-thesqltocalltheprocedure
- *@paramparameters
- *-theparametersfortheprocedure
- *@paramskipResults
- *-thenumberofresultstoskip
- *@parammaxResults
- *-themaximumnumberofresultstoreturn
- *@paramcallback
- *-arowhandlerforprocessingtheresults
- *@throwsSQLException
- *-iftheprocedurefails
- */
- publicvoidexecuteQueryProcedure(StatementScopestatementScope,
- Connectionconn,Stringsql,Object[]parameters,intskipResults,
- intmaxResults,RowHandlerCallbackcallback)throwsSQLException{
- ErrorContexterrorContext=statementScope.getErrorContext();
- errorContext.setActivity("executingqueryprocedure");
- errorContext.setObjectId(sql);
- CallableStatementcs=null;
- ResultSetrs=null;
- setupResultObjectFactory(statementScope);
- try{
- errorContext
- .setMoreInfo("ChecktheSQLStatement(preparationfailed).");
- IntegerrsType=statementScope.getStatement().getResultSetType();
- if(rsType!=null){
- cs=prepareCall(statementScope.getSession(),conn,sql,rsType);
- }else{
- cs=prepareCall(statementScope.getSession(),conn,sql);
- }
- setStatementTimeout(statementScope.getStatement(),cs);
- IntegerfetchSize=statementScope.getStatement().getFetchSize();
- if(fetchSize!=null){
- cs.setFetchSize(fetchSize.intValue());
- }
- ParameterMapparameterMap=statementScope.getParameterMap();
- ParameterMapping[]mappings=parameterMap.getParameterMappings();
- errorContext
- .setMoreInfo("Checktheoutputparameters(registeroutputparametersfailed).");
- registerOutputParameters(cs,mappings);
- errorContext
- .setMoreInfo("Checktheparameters(setparametersfailed).");
- parameterMap.setParameters(statementScope,cs,parameters);
- errorContext
- .setMoreInfo("Checkthestatement(updateprocedurefailed).");
- cs.execute();
- errorContext
- .setMoreInfo("Checktheresults(failedtoretrieveresults).");
- //BeginResultSetHandling
- rs=handleMultipleResults(cs,statementScope,skipResults,
- maxResults,callback);
- //EndResultSetHandling
- errorContext
- .setMoreInfo("Checktheoutputparameters(retrievalofoutputparametersfailed).");
- retrieveOutputParameters(statementScope,cs,mappings,parameters,
- callback);
- }finally{
- try{
- closeResultSet(rs);
- }finally{
- closeStatement(statementScope.getSession(),cs);
- }
- }
- }
- privateResultSethandleMultipleResults(PreparedStatementps,
- StatementScopestatementScope,intskipResults,intmaxResults,
- RowHandlerCallbackcallback)throwsSQLException{
- ResultSetrs;
- rs=getFirstResultSet(statementScope,ps);
- if(rs!=null){
- handleResults(statementScope,rs,skipResults,maxResults,callback);
- }
- //MultipleResultSethandling
- if(callback.getRowHandler()instanceofDefaultRowHandler){
- MappedStatementstatement=statementScope.getStatement();
- DefaultRowHandlerdefaultRowHandler=((DefaultRowHandler)callback
- .getRowHandler());
- if(statement.hasMultipleResultMaps()){
- ListmultipleResults=newArrayList();
- multipleResults.add(defaultRowHandler.getList());
- ResultMap[]resultMaps=statement.getAdditionalResultMaps();
- inti=0;
- while(moveToNextResultsSafely(statementScope,ps)){
- if(i>=resultMaps.length)
- break;
- ResultMaprm=resultMaps[i];
- statementScope.setResultMap(rm);
- rs=ps.getResultSet();
- DefaultRowHandlerrh=newDefaultRowHandler();
- handleResults(statementScope,rs,skipResults,maxResults,
- newRowHandlerCallback(rm,null,rh));
- multipleResults.add(rh.getList());
- i++;
- }
- defaultRowHandler.setList(multipleResults);
- statementScope.setResultMap(statement.getResultMap());
- }else{
- while(moveToNextResultsSafely(statementScope,ps))
- ;
- }
- }
- //EndadditionalResultSethandling
- returnrs;
- }
- privateResultSetgetFirstResultSet(StatementScopescope,Statementstmt)
- throwsSQLException{
- ResultSetrs=null;
- booleanhasMoreResults=true;
- while(hasMoreResults){
- rs=stmt.getResultSet();
- if(rs!=null){
- break;
- }
- hasMoreResults=moveToNextResultsIfPresent(scope,stmt);
- }
- returnrs;
- }
- privatebooleanmoveToNextResultsIfPresent(StatementScopescope,
- Statementstmt)throwsSQLException{
- booleanmoreResults;
- //ThisisthemessedupJDBCapproachfordeterminingiftherearemore
- //results
- moreResults=!(((moveToNextResultsSafely(scope,stmt)==false)&&(stmt
- .getUpdateCount()==-1)));
- returnmoreResults;
- }
- privatebooleanmoveToNextResultsSafely(StatementScopescope,Statementstmt)
- throwsSQLException{
- if(forceMultipleResultSetSupport(scope)
- ||stmt.getConnection().getMetaData()
- .supportsMultipleResultSets()){
- returnstmt.getMoreResults();
- }
- returnfalse;
- }
- privatebooleanforceMultipleResultSetSupport(StatementScopescope){
- return((SqlMapClientImpl)scope.getSession().getSqlMapClient())
- .getDelegate().isForceMultipleResultSetSupport();
- }
- privatevoidhandleResults(StatementScopestatementScope,ResultSetrs,
- intskipResults,intmaxResults,RowHandlerCallbackcallback)
- throwsSQLException{
- try{
- statementScope.setResultSet(rs);
- ResultMapresultMap=statementScope.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(
- statementScope,rs).getResults(statementScope,rs);
- callback.handleResultObject(statementScope,columnValues,
- rs);
- resultsFetched++;
- }
- }
- }finally{
- statementScope.setResultSet(null);
- }
- }
- privatevoidretrieveOutputParameters(StatementScopestatementScope,
- CallableStatementcs,ParameterMapping[]mappings,
- Object[]parameters,RowHandlerCallbackcallback)
- throwsSQLException{
- for(inti=0;i<mappings.length;i++){
- ParameterMappingmapping=((ParameterMapping)mappings[i]);
- if(mapping.isOutputAllowed()){
- if("java.sql.ResultSet".equalsIgnoreCase(mapping
- .getJavaTypeName())){
- ResultSetrs=(ResultSet)cs.getObject(i+1);
- ResultMapresultMap;
- if(mapping.getResultMapName()==null){
- resultMap=statementScope.getResultMap();
- handleOutputParameterResults(statementScope,resultMap,
- rs,callback);
- }else{
- SqlMapClientImplclient=(SqlMapClientImpl)statementScope
- .getSession().getSqlMapClient();
- resultMap=client.getDelegate().getResultMap(
- mapping.getResultMapName());
- DefaultRowHandlerrowHandler=newDefaultRowHandler();
- RowHandlerCallbackhandlerCallback=newRowHandlerCallback(
- resultMap,null,rowHandler);
- handleOutputParameterResults(statementScope,resultMap,
- rs,handlerCallback);
- parameters[i]=rowHandler.getList();
- }
- rs.close();
- }else{
- parameters[i]=mapping.getTypeHandler().getResult(cs,
- i+1);
- }
- }
- }
- }
- privatevoidregisterOutputParameters(CallableStatementcs,
- ParameterMapping[]mappings)throwsSQLException{
- for(inti=0;i<mappings.length;i++){
- ParameterMappingmapping=((ParameterMapping)mappings[i]);
- if(mapping.isOutputAllowed()){
- if(null!=mapping.getTypeName()
- &&!mapping.getTypeName().equals("")){//@added
- cs.registerOutParameter(i+1,mapping.getJdbcType(),
- mapping.getTypeName());
- }else{
- if(mapping.getNumericScale()!=null
- &&(mapping.getJdbcType()==Types.NUMERIC||mapping
- .getJdbcType()==Types.DECIMAL)){
- cs.registerOutParameter(i+1,mapping.getJdbcType(),
- mapping.getNumericScale().intValue());
- }else{
- cs.registerOutParameter(i+1,mapping.getJdbcType());
- }
- }
- }
- }
- }
- privatevoidhandleOutputParameterResults(StatementScopestatementScope,
- ResultMapresultMap,ResultSetrs,RowHandlerCallbackcallback)
- throwsSQLException{
- ResultMaporig=statementScope.getResultMap();
- try{
- statementScope.setResultSet(rs);
- if(resultMap!=null){
- statementScope.setResultMap(resultMap);
- //GetResults
- while(rs.next()){
- Object[]columnValues=resultMap.resolveSubMap(
- statementScope,rs).getResults(statementScope,rs);
- callback.handleResultObject(statementScope,columnValues,
- rs);
- }
- }
- }finally{
- statementScope.setResultSet(null);
- statementScope.setResultMap(orig);
- }
- }
- /**
- *Cleanupanybatchesonthesession
- *
- *@paramsessionScope
- *-thesessiontocleanup
- */
- publicvoidcleanup(SessionScopesessionScope){
- Batchbatch=(Batch)sessionScope.getBatch();
- if(batch!=null){
- batch.cleanupBatch(sessionScope);
- sessionScope.setBatch(null);
- }
- }
- privatePreparedStatementprepareStatement(SessionScopesessionScope,
- Connectionconn,Stringsql,IntegerrsType)throwsSQLException{
- SqlMapExecutorDelegatedelegate=((SqlMapClientImpl)sessionScope
- .getSqlMapExecutor()).getDelegate();
- if(sessionScope.hasPreparedStatementFor(sql)){
- returnsessionScope.getPreparedStatement((sql));
- }else{
- PreparedStatementps=conn.prepareStatement(sql,
- rsType.intValue(),ResultSet.CONCUR_READ_ONLY);
- sessionScope.putPreparedStatement(delegate,sql,ps);
- returnps;
- }
- }
- privateCallableStatementprepareCall(SessionScopesessionScope,
- Connectionconn,Stringsql,IntegerrsType)throwsSQLException{
- SqlMapExecutorDelegatedelegate=((SqlMapClientImpl)sessionScope
- .getSqlMapExecutor()).getDelegate();
- if(sessionScope.hasPreparedStatementFor(sql)){
- return(CallableStatement)sessionScope.getPreparedStatement((sql));
- }else{
- CallableStatementcs=conn.prepareCall(sql,rsType.intValue(),
- ResultSet.CONCUR_READ_ONLY);
- sessionScope.putPreparedStatement(delegate,sql,cs);
- returncs;
- }
- }
- privatestaticPreparedStatementprepareStatement(
- SessionScopesessionScope,Connectionconn,Stringsql)
- throwsSQLException{
- SqlMapExecutorDelegatedelegate=((SqlMapClientImpl)sessionScope
- .getSqlMapExecutor()).getDelegate();
- if(sessionScope.hasPreparedStatementFor(sql)){
- returnsessionScope.getPreparedStatement((sql));
- }else{
- PreparedStatementps=conn.prepareStatement(sql);
- sessionScope.putPreparedStatement(delegate,sql,ps);
- returnps;
- }
- }
- privateCallableStatementprepareCall(SessionScopesessionScope,
- Connectionconn,Stringsql)throwsSQLException{
- SqlMapExecutorDelegatedelegate=((SqlMapClientImpl)sessionScope
- .getSqlMapExecutor()).getDelegate();
- if(sessionScope.hasPreparedStatementFor(sql)){
- return(CallableStatement)sessionScope.getPreparedStatement((sql));
- }else{
- CallableStatementcs=conn.prepareCall(sql);
- sessionScope.putPreparedStatement(delegate,sql,cs);
- returncs;
- }
- }
- privatestaticvoidcloseStatement(SessionScopesessionScope,
- PreparedStatementps){
- if(ps!=null){
- if(!sessionScope.hasPreparedStatement(ps)){
- try{
- ps.close();
- }catch(SQLExceptione){
- //ignore
- }
- }
- }
- }
- /**
- *@paramrs
- */
- privatestaticvoidcloseResultSet(ResultSetrs){
- if(rs!=null){
- try{
- rs.close();
- }catch(SQLExceptione){
- //ignore
- }
- }
- }
- privatestaticvoidsetStatementTimeout(MappedStatementmappedStatement,
- Statementstatement)throwsSQLException{
- if(mappedStatement.getTimeout()!=null){
- statement.setQueryTimeout(mappedStatement.getTimeout().intValue());
- }
- }
- //
- //InnerClasses
- //
- privatestaticclassBatch{
- privateStringcurrentSql;
- privateListstatementList=newArrayList();
- privateListbatchResultList=newArrayList();
- privateintsize;
- /**
- *Createanewbatch
- */
- publicBatch(){
- this.size=0;
- }
- /**
- *Getterforthebatchsize
- *
- *@return-thebatchsize
- */
- publicintgetSize(){
- returnsize;
- }
- /**
- *Addapreparedstatementtothebatch
- *
- *@paramstatementScope
- *-therequestscope
- *@paramconn
- *-thedatabaseconnection
- *@paramsql
- *-theSQLtoadd
- *@paramparameters
- *-theparametersfortheSQL
- *@throwsSQLException
- *-ifthepreparefortheSQLfails
- */
- publicvoidaddBatch(StatementScopestatementScope,Connectionconn,
- Stringsql,Object[]parameters)throwsSQLException{
- PreparedStatementps=null;
- if(currentSql!=null&¤tSql.equals(sql)){
- intlast=statementList.size()-1;
- ps=(PreparedStatement)statementList.get(last);
- }else{
- ps=prepareStatement(statementScope.getSession(),conn,sql);
- setStatementTimeout(statementScope.getStatement(),ps);
- currentSql=sql;
- statementList.add(ps);
- batchResultList.add(newBatchResult(statementScope
- .getStatement().getId(),sql));
- }
- statementScope.getParameterMap().setParameters(statementScope,ps,
- parameters);
- ps.addBatch();
- size++;
- }
- /**
- *TODO(JeffButler)-maybethismethodshouldbedeprecatedinsome
- *release,andthenremovedinsomeevenlaterrelease.
- *executeBatchDetailedgivesmuchmorecompleteinformation.<p/>
- *Executethecurrentsession'sbatch
- *
- *@return-thenumberofrowsupdated
- *@throwsSQLException
- *-ifthebatchfails
- */
- publicintexecuteBatch()throwsSQLException{
- inttotalRowCount=0;
- for(inti=0,n=statementList.size();i<n;i++){
- PreparedStatementps=(PreparedStatement)statementList.get(i);
- int[]rowCounts=ps.executeBatch();
- for(intj=0;j<rowCounts.length;j++){
- if(rowCounts[j]==Statement.SUCCESS_NO_INFO){
- //donothing
- }elseif(rowCounts[j]==Statement.EXECUTE_FAILED){
- thrownewSQLException(
- "Thebatchedstatementatindex"+j
- +"failedtoexecute.");
- }else{
- totalRowCount+=rowCounts[j];
- }
- }
- }
- returntotalRowCount;
- }
- /**
- *Batchexecutionmethodthatreturnsalltheinformationthedriver
- *hastooffer.
- *
- *@returnaListofBatchResultobjects
- *@throwsBatchException
- *(anSQLExceptionsubclass)ifanynestedbatchfails
- *@throwsSQLException
- *ifadatabaseaccesserroroccurs,orthedrivedoesnot
- *supportbatchstatements
- *@throwsBatchException
- *ifthedriverthrowsBatchUpdateException
- */
- publicListexecuteBatchDetailed()throwsSQLException,BatchException{
- Listanswer=newArrayList();
- for(inti=0,n=statementList.size();i<n;i++){
- BatchResultbr=(BatchResult)batchResultList.get(i);
- PreparedStatementps=(PreparedStatement)statementList.get(i);
- try{
- br.setUpdateCounts(ps.executeBatch());
- }catch(BatchUpdateExceptione){
- StringBuffermessage=newStringBuffer();
- message.append("Subbatchnumber");
- message.append(i+1);
- message.append("failed.");
- if(i>0){
- message.append("");
- message.append(i);
- message
- .append("priorsubbatch(s)completedsuccessfully,butwillberolledback.");
- }
- thrownewBatchException(message.toString(),e,answer,br
- .getStatementId(),br.getSql());
- }
- answer.add(br);
- }
- returnanswer;
- }
- /**
- *Closeallthestatementsinthebatchandclearallthestatements
- *
- *@paramsessionScope
- */
- publicvoidcleanupBatch(SessionScopesessionScope){
- for(inti=0,n=statementList.size();i<n;i++){
- PreparedStatementps=(PreparedStatement)statementList.get(i);
- closeStatement(sessionScope,ps);
- }
- currentSql=null;
- statementList.clear();
- batchResultList.clear();
- size=0;
- }
- }
- privatevoidsetupResultObjectFactory(StatementScopestatementScope){
- SqlMapClientImplclient=(SqlMapClientImpl)statementScope
- .getSession().getSqlMapClient();
- ResultObjectFactoryUtil.setResultObjectFactory(client
- .getResultObjectFactory());
- ResultObjectFactoryUtil.setStatementId(statementScope.getStatement()
- .getId());
- }
- }
Dialect.java
- packagecom.ibatis.sqlmap.engine.execution;
- publicclassDialect{
- privatestaticfinalStringSQL_END_DELIMITER=";";
- publicstaticStringgetLimitString(StringdbName,Stringsql,intoffset,
- intlimit){
- StringlimitString=sql;
- if(dbName.toLowerCase().indexOf("mysql")!=-1){
- limitString=getMysqlLimitString(sql,offset,limit);
- }
- if(dbName.toLowerCase().indexOf("microsoftsqlserver")!=-1){
- limitString=getMssqlLimitString(sql,offset,limit);
- }
- if(dbName.toLowerCase().indexOf("oracle")!=-1){
- limitString=getOracleLimitString(sql,offset,limit);
- }
- if(dbName.toLowerCase().indexOf("db2")!=-1){
- limitString=getDB2LimitString(sql,offset,limit);
- }
- returnlimitString;
- }
- privatestaticStringgetMysqlLimitString(Stringsql,intoffset,intlimit){
- sql=trim(sql);
- StringBuffersb=newStringBuffer(sql.length()+20);
- sb.append(sql);
- if(offset>0){
- sb.append("limit").append(offset).append(',').append(limit);
- }else{
- sb.append("limit").append(limit);
- }
- returnsb.toString();
- }
- privatestaticStringgetOracleLimitString(Stringsql,intoffset,intlimit){
- sql=trim(sql);
- StringBuffersb=newStringBuffer(sql.length()+100);
- if(offset>0){
- sb.append("select*from(selectrow_.*,rownumrownum_from(")
- .append(sql).append(")row_whererownum<=").append(
- offset+limit).append(")whererownum_>")
- .append(offset);
- }else{
- sb.append("select*from(").append(sql).append(
- ")whererownum<=").append(limit);
- }
- returnsb.toString();
- }
- privatestaticStringgetMssqlLimitString(Stringsql,intoffset,intlimit){
- returnnull;
- }
- privatestaticStringgetDB2LimitString(Stringsql,intoffset,intlimit){
- returnnull;
- }
- privatestaticStringtrim(Stringsql){
- sql=sql.trim();
- if(sql.endsWith(SQL_END_DELIMITER)){
- sql=sql.substring(0,sql.length()-1
- -SQL_END_DELIMITER.length());
- }
- returnsql;
- }
- }