ibatis源码分析—运行流程解析(二)

二、具体流程

1、流程入口。一般都是在XXXDAOImpl中调用了getSqlMapClientTmplate().queryXXXX()方法。

2、方法入口。getSqlMapClientTmplate类的execute()方法为具体执行方法,参数为一个匿名内部类,用于回调doInSqlMapClient()方法。


public <T> T execute(SqlMapClientCallback<T> action) throws DataAccessException {
		Assert.notNull(action, "Callback object must not be null");
		Assert.notNull(this.sqlMapClient, "No SqlMapClient specified");
		//创建SqlMapSessionImpl对象,这个对象用来维持数据交互的环境。
		SqlMapSession session = this.sqlMapClient.openSession();
		if (logger.isDebugEnabled()) {
			logger.debug("Opened SqlMapSession [" + session + "] for iBATIS operation");
		}
		Connection ibatisCon = null

		try {
			Connection springCon = null;
			//获取数据源
			DataSource dataSource = getDataSource();
			boolean transactionAware = (dataSource instanceof TransactionAwareDataSourceProxy);

			// Obtain JDBC Connection to operate on...
			try {
				ibatisCon = session.getCurrentConnection();
				if (ibatisCon == null) {
					springCon = (transactionAware ?
							dataSource.getConnection() : DataSourceUtils.doGetConnection(dataSource));
					//设置数据源		
					session.setUserConnection(springCon);
					if (logger.isDebugEnabled()) {
						logger.debug("Obtained JDBC Connection [" + springCon + "] for iBATIS operation");
					}
				}
				else {
					if (logger.isDebugEnabled()) {
						logger.debug("Reusing JDBC Connection [" + ibatisCon + "] for iBATIS operation");
					}
				}
			}
			catch (SQLException ex) {
				throw new CannotGetJdbcConnectionException("Could not get JDBC Connection", ex);
			}

			// Execute given callback...
			try {
                        	//进行回调。
				return action.doInSqlMapClient(session);
			}
			catch (SQLException ex) {
				throw getExceptionTranslator().translate("SqlMapClient operation", null, ex);
			}
			finally {
				try {
					if (springCon != null) {
						if (transactionAware) {
							springCon.close();
						}
						else {
							DataSourceUtils.doReleaseConnection(springCon, dataSource);
						}
					}
				}
				catch (Throwable ex) {
					logger.debug("Could not close JDBC Connection", ex);
				}
			}

			// Processing finished - potentially session still to be closed.
		}
		finally {
			//关闭连接
			if (ibatisCon == null) {
				session.close();
			}
		}
	}




3、回调方法。

public Object queryForObject(String id, Object paramObject, Object resultObject) throws SQLException {
    //调用SqlMapExecutorDelegate这个代理类进行操作
    return delegate.queryForObject(session, id, paramObject, resultObject);
}


 

4、设置获取statement和初始化request

public Object queryForObject(SessionScope session, String id, Object paramObject, Object resultObject) throws SQLException {
    Object object = null;
    //根据上送的id,在mappedStatements这个map中获取当前的statement
    MappedStatement ms = getMappedStatement(id);
    //获取当前的事物
    Transaction trans = getTransaction(session);
    boolean autoStart = trans == null;

    try {
      trans = autoStartTransaction(session, autoStart, trans);
      //从requestpool中取出一个request,把session数据都放入到request中,以后的执行环境为request
      RequestScope request = popRequest(session, ms);
      try {
        //
        object = ms.executeQueryForObject(request, trans, paramObject, resultObject);
      } finally {
        pushRequest(request);
      }

      autoCommitTransaction(session, autoStart);
    } finally {
      autoEndTransaction(session, autoStart);
    }

    return object;
  }


</pre><pre name="code" class="java">protected RequestScope popRequest(SessionScope session, MappedStatement mappedStatement) {
    //requestpool中获取request
    RequestScope request = (RequestScope) requestPool.pop();
    session.incrementRequestStackDepth();
    request.setSession(session);
    //初始化request
    mappedStatement.initRequest(request);
    return request;
  }

</pre><p style="margin-top:0px; margin-bottom:0px; font-size:14px; font-family:Monaco"></p><pre name="code" class="java">
public void initRequest(RequestScope request) {
    //将statement、parameterMap、resultMap、Sql对象都放入到request中
    request.setStatement(this);
    request.setParameterMap(parameterMap);
    request.setResultMap(resultMap);
    request.setSql(sql);
  }



5、交互的数据以及环境准备好后,就进行数据交互

public Object executeQueryForObject(RequestScope request, Transaction trans, Object parameterObject, Object resultObject)
      throws SQLException {
    try {
      Object object = null;

      DefaultRowHandler rowHandler = new DefaultRowHandler();
      //查询方法
      executeQueryWithCallback(request, trans.getConnection(), parameterObject, resultObject, rowHandler, SqlExecutor.NO_SKIPPED_RESULTS, SqlExecutor.NO_MAXIMUM_RESULTS);
      List list = rowHandler.getList();
      //对结果的处理executeQueryForObject为查询单个对象。
      if (list.size() > 1) {
        throw new SQLException("Error: executeQueryForObject returned too many results.");
      } else if (list.size() > 0) {
        object = list.get(0);
      }

      return object;
    } catch (TransactionException e) {
      throw new NestedSQLException("Error getting Connection from Transaction.  Cause: " + e, e);
    }
  }


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对象,该对象对象可能有3种实力,dynamicsql,simpledynamicsql,staticsql。
      Sql sql = getSql();
      //获取ParameterMap,如果是simpledynamicsql,staticsql则直接从request中获取,如果是dynamicsql则需要重新处理
      errorContext.setMoreInfo("Check the parameter map.");
      ParameterMap parameterMap = sql.getParameterMap(request, parameterObject);
      //获取ResultMap,都从request中获取
      errorContext.setMoreInfo("Check the result map.");
      ResultMap resultMap = sql.getResultMap(request, parameterObject);

      request.setResultMap(resultMap);
      request.setParameterMap(parameterMap);
      //获取参数值。通过dataexchange对象获取,该对象有多种实例,具体是哪种取决于parameterClass,请看DataExchangeFactory类
      errorContext.setMoreInfo("Check the parameter map.");
      Object[] parameters = parameterMap.getParameterObjectValues(request, parameterObject);

      errorContext.setMoreInfo("Check the SQL statement.");
      //获取当前的sql
      String sqlString = sql.getSql(request, parameterObject);

      errorContext.setActivity("executing mapped statement");
      errorContext.setMoreInfo("Check the SQL statement or the result map.");
      RowHandlerCallback callback = new RowHandlerCallback(resultMap, resultObject, rowHandler);
      //调用SqlExecutor的executeQuery方法()进行查询。
      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);
    }
  }


</pre><pre name="code" class="java">public void executeQuery(RequestScope request, Connection conn, String sql, Object[] parameters, int skipResults, int maxResults, RowHandlerCallback callback) throws SQLException {
    ErrorContext errorContext = request.getErrorContext();
    errorContext.setActivity("executing query");
    errorContext.setObjectId(sql);
    PreparedStatement ps = null;
    ResultSet rs = null;
    setupResultObjectFactory(request);
    try {
      errorContext.setMoreInfo("Check the SQL Statement (preparation failed).");
      Integer rsType = request.getStatement().getResultSetType();
      //初始化ps
      if (rsType != null) {
        ps = prepareStatement(request.getSession(), conn, sql, rsType);
      } else {
        ps = prepareStatement(request.getSession(), conn, sql);
      }
      setStatementTimeout(request.getStatement(), ps);
      Integer fetchSize = request.getStatement().getFetchSize();
      if (fetchSize != null) {
        ps.setFetchSize(fetchSize.intValue());
      }
      errorContext.setMoreInfo("Check the parameters (set parameters failed).");
      request.getParameterMap().setParameters(request, ps, parameters);
      errorContext.setMoreInfo("Check the statement (query failed).");
      //执行sql,这里只是个代理方法。
      ps.execute();
      errorContext.setMoreInfo("Check the results (failed to retrieve results).");

      //callback为回调参数,将result放入到callback中
      rs = handleMultipleResults(ps, request, skipResults, maxResults, callback);
      //
    } finally {
      try {
        closeResultSet(rs);
      } finally {
        closeStatement(request.getSession(), ps);
      }
    }

  }

 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值