二、具体流程
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();
}
}
}
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);
}
}
}