Terry.Li-彬

          虛其心,可解天下之問(wèn);專其心,可治天下之學(xué);靜其心,可悟天下之理;恒其心,可成天下之業(yè)。

            BlogJava :: 首頁(yè) :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
            143 隨筆 :: 344 文章 :: 130 評(píng)論 :: 0 Trackbacks
          下面的內(nèi)容是基于ibatis2.2,以后的版本是否提供了類似功能不太清楚,甚至這個(gè)版本是否提供也沒(méi)有細(xì)究(好像沒(méi)有)。

          很多時(shí)候我們需要執(zhí)行select語(yǔ)句對(duì)應(yīng)的count語(yǔ)句,例如分頁(yè)查詢時(shí)要得到結(jié)果的記錄數(shù),但在ibatis的映射文件中我們只想寫一條select語(yǔ)句,而count語(yǔ)句直接由這條語(yǔ)句生成,這可以省去很多不必要的語(yǔ)句關(guān)聯(lián),下面的代碼可以實(shí)現(xiàn)這一點(diǎn)。

          CountStatementUtil.java

          java 代碼
          package com.aladdin.dao.ibatis.ext;

          import java.sql.Connection;
          import java.sql.SQLException;
          import java.util.List;

          import com.aladdin.util.ReflectUtil;
          import com.ibatis.common.jdbc.exception.NestedSQLException;
          import com.ibatis.sqlmap.client.event.RowHandler;
          import com.ibatis.sqlmap.engine.impl.ExtendedSqlMapClient;
          import com.ibatis.sqlmap.engine.mapping.parameter.ParameterMap;
          import com.ibatis.sqlmap.engine.mapping.result.AutoResultMap;
          import com.ibatis.sqlmap.engine.mapping.result.BasicResultMap;
          import com.ibatis.sqlmap.engine.mapping.result.ResultMap;
          import com.ibatis.sqlmap.engine.mapping.sql.Sql;
          import com.ibatis.sqlmap.engine.mapping.statement.ExecuteListener;
          import com.ibatis.sqlmap.engine.mapping.statement.MappedStatement;
          import com.ibatis.sqlmap.engine.mapping.statement.RowHandlerCallback;
          import com.ibatis.sqlmap.engine.mapping.statement.SelectStatement;
          import com.ibatis.sqlmap.engine.scope.ErrorContext;
          import com.ibatis.sqlmap.engine.scope.RequestScope;

          public class CountStatementUtil {

          public static MappedStatement createCountStatement(MappedStatement selectStatement) {
          return new CountStatement((SelectStatement) selectStatement);
          }

          public static String getCountStatementId(String selectStatementId) {
          return "__" + selectStatementId + "Count__";
          }

          }

          class CountStatement extends SelectStatement {

          public CountStatement(SelectStatement selectStatement) {
          super();
          setId(CountStatementUtil.getCountStatementId(selectStatement
          .getId()));
          setResultSetType(selectStatement.getResultSetType());
          setFetchSize(1);
          setParameterMap(selectStatement.getParameterMap());
          setParameterClass(selectStatement.getParameterClass());
          setSql(selectStatement.getSql());
          setResource(selectStatement.getResource());
          setSqlMapClient(selectStatement.getSqlMapClient());
          setTimeout(selectStatement.getTimeout());
          List executeListeners = (List) ReflectUtil.getFieldValue(
          selectStatement, "executeListeners", List.class);
          if (executeListeners != null) {
          for (Object listener : executeListeners) {
          addExecuteListener((ExecuteListener) listener);
          }
          }
          BasicResultMap resultMap = new AutoResultMap(
          ((ExtendedSqlMapClient) getSqlMapClient()).getDelegate(), false);
          resultMap.setId(getId() + "-AutoResultMap");
          resultMap.setResultClass(Long.class);
          resultMap.setResource(getResource());
          setResultMap(resultMap);

          }

          protected void executeQueryWithCallback(RequestScope request,
          Connection conn, Object parameterObject, Object resultObject,
          RowHandler rowHandler, int skipResults, int maxResults)
          throws SQLException {
          ErrorContext errorContext = request.getErrorContext();
          errorContext
          .setActivity("preparing the mapped statement for execution");
          errorContext.setObjectId(this.getId());
          errorContext.setResource(this.getResource());

          try {
          parameterObject = validateParameter(parameterObject);

          Sql sql = getSql();

          errorContext.setMoreInfo("Check the parameter map.");
          ParameterMap parameterMap = sql.getParameterMap(request,
          parameterObject);

          errorContext.setMoreInfo("Check the result map.");
          ResultMap resultMap = getResultMap(request, parameterObject, sql);

          request.setResultMap(resultMap);
          request.setParameterMap(parameterMap);

          errorContext.setMoreInfo("Check the parameter map.");
          Object[] parameters = parameterMap.getParameterObjectValues(
          request, parameterObject);

          errorContext.setMoreInfo("Check the SQL statement.");
          String sqlString = getSqlString(request, parameterObject, sql);

          errorContext.setActivity("executing mapped statement");
          errorContext
          .setMoreInfo("Check the SQL statement or the result map.");
          RowHandlerCallback callback = new RowHandlerCallback(resultMap,
          resultObject, rowHandler);
          sqlExecuteQuery(request, conn, sqlString, parameters, skipResults,
          maxResults, callback);

          errorContext.setMoreInfo("Check the output parameters.");
          if (parameterObject != null) {
          postProcessParameterObject(request, parameterObject, parameters);
          }

          errorContext.reset();
          sql.cleanup(request);
          notifyListeners();
          } catch (SQLException e) {
          errorContext.setCause(e);
          throw new NestedSQLException(errorContext.toString(), e
          .getSQLState(), e.getErrorCode(), e);
          } catch (Exception e) {
          errorContext.setCause(e);
          throw new NestedSQLException(errorContext.toString(), e);
          }
          }

          private String getSqlString(RequestScope request, Object parameterObject,
          Sql sql) {
          String sqlString = sql.getSql(request, parameterObject);
          int start = sqlString.toLowerCase().indexOf("from");
          if (start >= 0) {
          sqlString = "SELECT COUNT(*) AS c " + sqlString.substring(start);
          }
          return sqlString;
          }

          private ResultMap getResultMap(RequestScope request,
          Object parameterObject, Sql sql) {
          return getResultMap();
          }

          }

          上面代碼中的getSqlString方法可以根據(jù)自己系統(tǒng)select語(yǔ)句的復(fù)雜程度完善,這里給出的是最簡(jiǎn)單的實(shí)現(xiàn)。

          使用上面的類即可由select語(yǔ)句生成count語(yǔ)句,下面是通過(guò)spring使用的代碼:

          BaseDaoiBatis.java

          java 代碼
          //...
          public abstract class BaseDaoiBatis extends SqlMapClientDaoSupport {

          //...

          protected long getObjectTotal(String selectQuery, Object parameterObject) {
          prepareCountQuery(selectQuery);
          //...
          return (Long) getSqlMapClientTemplate().queryForObject(
          CountStatementUtil.getCountStatementId(selectQuery),
          parameterObject);
          }

          protected void prepareCountQuery(String selectQuery) {

          String countQuery = CountStatementUtil.getCountStatementId(selectQuery);
          if (logger.isDebugEnabled()) {
          logger.debug("Convert " + selectQuery + " to " + countQuery);
          }
          SqlMapClient sqlMapClient = getSqlMapClientTemplate().getSqlMapClient();
          if (sqlMapClient instanceof ExtendedSqlMapClient) {
          SqlMapExecutorDelegate delegate = ((ExtendedSqlMapClient) sqlMapClient)
          .getDelegate();
          try {
          delegate.getMappedStatement(countQuery);
          } catch (SqlMapException e) {
          delegate.addMappedStatement(CountStatementUtil
          .createCountStatement(delegate
          .getMappedStatement(selectQuery)));
          }

          }
          }

          //...
          }
          posted on 2008-05-03 00:31 禮物 閱讀(4802) 評(píng)論(3)  編輯  收藏 所屬分類: ibatis + spring

          評(píng)論

          # re: ibatis中由SELECT語(yǔ)句自動(dòng)生成COUNT語(yǔ)句 2011-01-13 12:18 tylerLimin
          Hi Terry.
          按你上面寫的那樣可以實(shí)現(xiàn)分頁(yè)條件中的 resultCount(記錄數(shù))統(tǒng)計(jì)嗎?它們是共用一條查詢語(yǔ)句?我試了試不行哦。不知你那里有沒(méi)有好的建議沒(méi),有,請(qǐng)回復(fù)。多謝!  回復(fù)  更多評(píng)論
            

          # re: ibatis中由SELECT語(yǔ)句自動(dòng)生成COUNT語(yǔ)句 2011-01-17 13:44 禮物
          可以實(shí)現(xiàn)count查詢,原則上會(huì)生成兩條sql語(yǔ)句,一條是count一條是具體分頁(yè)的,這個(gè)代碼已經(jīng)寫了很早了,你最好進(jìn)行debug跟蹤一下就可以知道了  回復(fù)  更多評(píng)論
            

          # re: ibatis中由SELECT語(yǔ)句自動(dòng)生成COUNT語(yǔ)句 2011-04-25 19:29 joliny
          有沒(méi)有通用的呀!!如果sql中包含子查詢就不好用了  回復(fù)  更多評(píng)論
            

          主站蜘蛛池模板: 平定县| 梨树县| 玛多县| 微博| 手游| 秦安县| 恩平市| 子长县| 东港市| 政和县| 金沙县| 巴楚县| 玉田县| 西安市| 静乐县| 疏勒县| 璧山县| 十堰市| 泰州市| 烟台市| 历史| 潮安县| 南京市| 拉萨市| 浦北县| 全椒县| 玉树县| 北票市| 达孜县| 虹口区| 涪陵区| 灵武市| 建湖县| 青州市| 仁布县| 都兰县| 金秀| 阿瓦提县| 灵璧县| 芮城县| 五原县|