Mybatis工作机制源码分析—一次insert请求处理流程

      本文从源码分析的角度分析Mybatis一次insert请求处理流程。

insert整体处理流程

时序图

Mybatis工作机制源码分析—一次insert请求处理流程_第1张图片

相关源码

/** SqlSessionTemplate.java */
public int insert(String statement, Object parameter) {
	return this.sqlSessionProxy.insert(statement, parameter);
}

// jdk动态代理
private class SqlSessionInterceptor implements InvocationHandler {
	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		// 获取SqlSession
		SqlSession sqlSession = getSqlSession(
			SqlSessionTemplate.this.sqlSessionFactory,
			SqlSessionTemplate.this.executorType,
			SqlSessionTemplate.this.exceptionTranslator);
		try {
			// 请求(select|insert|update|delete)处理,这里采用动态代理
			Object result = method.invoke(sqlSession, args);
			if (!isSqlSessionTransactional(sqlSession, SqlSessionTemplate.this.sqlSessionFactory)) {
			  // force commit even on non-dirty sessions because some databases require
			  // a commit/rollback before calling close()
			  sqlSession.commit(true); // 非Spring管理的事务,手工提交
			}
			return result;
		} catch (Throwable t) {
			Throwable unwrapped = unwrapThrowable(t);
			if (SqlSessionTemplate.this.exceptionTranslator != null && unwrapped instanceof PersistenceException) {
			  // release the connection to avoid a deadlock if the translator is no loaded. See issue #22
			  closeSqlSession(sqlSession, SqlSessionTemplate.this.sqlSessionFactory);
			  sqlSession = null;
			  Throwable translated = SqlSessionTemplate.this.exceptionTranslator.translateExceptionIfPossible((PersistenceException) unwrapped);
			  if (translated != null) {
				unwrapped = translated;
			  }
			}
			throw unwrapped;
		} finally {
			if (sqlSession != null) {
			  // 请求处理完成后,sqlSession释放或保留
			  closeSqlSession(sqlSession, SqlSessionTemplate.this.sqlSessionFactory);
			}
		}
	}
}

// 对使用后的SqlSession进行相关处理
public static void closeSqlSession(SqlSession session, SqlSessionFactory sessionFactory) {
	notNull(session, NO_SQL_SESSION_SPECIFIED);
	notNull(sessionFactory, NO_SQL_SESSION_FACTORY_SPECIFIED);

	SqlSessionHolder holder = (SqlSessionHolder) TransactionSynchronizationManager.getResource(sessionFactory);
	if ((holder != null) && (holder.getSqlSession() == session)) {
	  // Spring Transactional下的SqlSession,不真正关闭sqlSession
	  if (LOGGER.isDebugEnabled()) {
		LOGGER.debug("Releasing transactional SqlSession [" + session + "]");
	  }
	  // 只进行sqlSessionHolder的referenceCount--
	  holder.released();
	} else {
	  if (LOGGER.isDebugEnabled()) {
		LOGGER.debug("Closing non transactional SqlSession [" + session + "]");
	  }
	  // 非Spring Transactional下的SqlSession,则SqlSession——>Executor——>Transaction——>DataSource——>Connection的close操作
	  session.close();
	}
}

SqlSessionUtils.getSqlSession工作流程

时序图

Mybatis工作机制源码分析—一次insert请求处理流程_第2张图片

相关类结构图

SqlSession类结构图:

Mybatis工作机制源码分析—一次insert请求处理流程_第3张图片

Executor类结构图:

Mybatis工作机制源码分析—一次insert请求处理流程_第4张图片

Transaction类结构图:

Mybatis工作机制源码分析—一次insert请求处理流程_第5张图片

SqlSession构建过程中的组件支持

Mybatis工作机制源码分析—一次insert请求处理流程_第6张图片

相关源码

/** SqlSessionUtils.java */
public static SqlSession getSqlSession(SqlSessionFactory sessionFactory, ExecutorType executorType, PersistenceExceptionTranslator exceptionTranslator) {

	notNull(sessionFactory, NO_SQL_SESSION_FACTORY_SPECIFIED);
	notNull(executorType, NO_EXECUTOR_TYPE_SPECIFIED);
	
	// 先从TransactionSynchronizationManager的事务资源缓存resources获取sessionFactory对应的SqlSessionHolder
	SqlSessionHolder holder = (SqlSessionHolder) TransactionSynchronizationManager.getResource(sessionFactory);

	// 从SqlSessionHolder中提取SqlSession
	SqlSession session = sessionHolder(executorType, holder);
	if (session != null) {
	  return session;
	}

	if (LOGGER.isDebugEnabled()) {
	  LOGGER.debug("Creating a new SqlSession");
	}

	// 打开新的SqlSession
	session = sessionFactory.openSession(executorType);

	// SpringManagedTransactionFactory下,缓存sessionHolder,进行Transaction synchronizations准备工作
	registerSessionHolder(sessionFactory, executorType, exceptionTranslator, session);

	return session;
}

// 从SqlSessionHolder中提取SqlSession,与Spring事务同步条件下才能提取
private static SqlSession sessionHolder(ExecutorType executorType, SqlSessionHolder holder) {
	SqlSession session = null;
	if (holder != null && holder.isSynchronizedWithTransaction()) { // sqlSessionHolder与Spring事务同步
	  if (holder.getExecutorType() != executorType) {
		throw new TransientDataAccessResourceException("Cannot change the ExecutorType when there is an existing transaction");
	  }

	  holder.requested(); // 引用次数加1

	  if (LOGGER.isDebugEnabled()) {
		LOGGER.debug("Fetched SqlSession [" + holder.getSqlSession() + "] from current transaction");
	  }

	  session = holder.getSqlSession(); // 获取sqlSession
	}
	return session;
}

/** TransactionSynchronizationManager.java */
public static Object getResource(Object key) {
	Object actualKey = TransactionSynchronizationUtils.unwrapResourceIfNecessary(key);
	Object value = doGetResource(actualKey);
	if (value != null && logger.isTraceEnabled()) {
		logger.trace("Retrieved value [" + value + "] for key [" + actualKey + "] bound to thread [" +
				Thread.currentThread().getName() + "]");
	}
	return value;
}

// 从TransactionSynchronizationManager的事务资源缓存ThreadLocal> resources获取actualKey对应的资源
// ThreadLocal模式,线程安全
private static Object doGetResource(Object actualKey) {
	Map map = resources.get();
	if (map == null) {
		return null;
	}
	Object value = map.get(actualKey);
	// Transparently remove ResourceHolder that was marked as void...
	if (value instanceof ResourceHolder && ((ResourceHolder) value).isVoid()) {
		map.remove(actualKey);
		// Remove entire ThreadLocal if empty...
		if (map.isEmpty()) {
			resources.remove();
		}
		value = null;
	}
	return value;
}

/** DefaultSqlSessionFactory.java */
public SqlSession openSession(ExecutorType execType) {
	return openSessionFromDataSource(execType, null, false);
}

private SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit) {
	Transaction tx = null;
	try {
	  // configuration属性获取environment
	  final Environment environment = configuration.getEnvironment();
	  // 从environment获取transactionFactory
	  final TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment);
	  // 打开新transaction,基于environment的dataSource
	  tx = transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit);
	  // 基于transaction、execType实例化executor
	  final Executor executor = configuration.newExecutor(tx, execType);
	  // 基于configuration、executor创建DefaultSqlSession
	  return new DefaultSqlSession(configuration, executor, autoCommit);
	} catch (Exception e) {
	  closeTransaction(tx); // may have fetched a connection so lets call close()
	  throw ExceptionFactory.wrapException("Error opening session.  Cause: " + e, e);
	} finally {
	  ErrorContext.instance().reset();
	}
}

// environment获取TransactionFactory
private TransactionFactory getTransactionFactoryFromEnvironment(Environment environment) {
	if (environment == null || environment.getTransactionFactory() == null) {
	  // 默认为ManagedTransactionFactory
	  return new ManagedTransactionFactory();
	}
	return environment.getTransactionFactory();
}

/** SpringManagedTransactionFactory.java */
// Spring容器管理下的transaction
public Transaction newTransaction(DataSource dataSource, TransactionIsolationLevel level, boolean autoCommit) {
	return new SpringManagedTransaction(dataSource);
}

/** Configuration.java */
public Executor newExecutor(Transaction transaction, ExecutorType executorType) {
	executorType = executorType == null ? defaultExecutorType : executorType;
	executorType = executorType == null ? ExecutorType.SIMPLE : executorType;
	Executor executor;
	if (ExecutorType.BATCH == executorType) {
	  executor = new BatchExecutor(this, transaction);
	} else if (ExecutorType.REUSE == executorType) {
	  executor = new ReuseExecutor(this, transaction);
	} else {
	  executor = new SimpleExecutor(this, transaction);
	}
	if (cacheEnabled) {
	  executor = new CachingExecutor(executor);
	}
	executor = (Executor) interceptorChain.pluginAll(executor);
	return executor;
}

/** SqlSessionUtils.java */
// 对于SpringManagedTransactionFactory,构建SqlSessionHolder,将其缓存到Transactional resources,且进行Transaction synchronizations标识
// 以便Spring容器进行事务管理
private static void registerSessionHolder(SqlSessionFactory sessionFactory, ExecutorType executorType,
  PersistenceExceptionTranslator exceptionTranslator, SqlSession session) {
	SqlSessionHolder holder;
	if (TransactionSynchronizationManager.isSynchronizationActive()) { // Transaction synchronizations至少已经初始化
	  Environment environment = sessionFactory.getConfiguration().getEnvironment();

	  // SpringManagedTransactionFactory才进行register SessionHolder工作
	  if (environment.getTransactionFactory() instanceof SpringManagedTransactionFactory) {
		if (LOGGER.isDebugEnabled()) {
		  LOGGER.debug("Registering transaction synchronization for SqlSession [" + session + "]");
		}
		
		// 构建SqlSessionHolder
		holder = new SqlSessionHolder(session, executorType, exceptionTranslator);
		// Transactional resources添加sessionFactory、holder键值对,resources为ThreadLocal>
		TransactionSynchronizationManager.bindResource(sessionFactory, holder);
		// Transaction synchronizations添加SqlSessionSynchronization,synchronizations为ThreadLocal>
		TransactionSynchronizationManager.registerSynchronization(new SqlSessionSynchronization(holder, sessionFactory));
		holder.setSynchronizedWithTransaction(true); // holder标识synchronizedWithTransaction为true
		holder.requested();
	  } else {
		if (TransactionSynchronizationManager.getResource(environment.getDataSource()) == null) {
		  if (LOGGER.isDebugEnabled()) {
			LOGGER.debug("SqlSession [" + session + "] was not registered for synchronization because DataSource is not transactional");
		  }
		} else {
		  throw new TransientDataAccessResourceException(
			  "SqlSessionFactory must be using a SpringManagedTransactionFactory in order to use Spring transaction synchronization");
		}
	  }
	} else {
	  if (LOGGER.isDebugEnabled()) {
		LOGGER.debug("SqlSession [" + session + "] was not registered for synchronization because synchronization is not active");
	  }
	}
}

DefaultSqlSession.insert工作流程

时序图

Mybatis工作机制源码分析—一次insert请求处理流程_第7张图片

相关类结构图

ObjectWrapper类结构图:

Mybatis工作机制源码分析—一次insert请求处理流程_第8张图片

相关Handler类结构图:

Mybatis工作机制源码分析—一次insert请求处理流程_第9张图片

TypeHandler类结构图:

Mybatis工作机制源码分析—一次insert请求处理流程_第10张图片

Mybatis一次请求处理核心流程(select|insert|update|delete)

Mybatis工作机制源码分析—一次insert请求处理流程_第11张图片

相关源码

/** DefaultSqlSession.java */
// 处理insert请求
// @param statement:statement id;@param parameter:输入参数
public int insert(String statement, Object parameter) {
	// 转给update进行处理
	return update(statement, parameter);
}

// 处理sql写的请求,包括insert、update、delete
public int update(String statement, Object parameter) {
	try {
	  dirty = true;
	  // 根据id获取MappedStatement
	  MappedStatement ms = configuration.getMappedStatement(statement);
	  // 
	  return executor.update(ms, wrapCollection(parameter));
	} catch (Exception e) {
	  throw ExceptionFactory.wrapException("Error updating database.  Cause: " + e, e);
	} finally {
	  ErrorContext.instance().reset();
	}
}

/** Configuration.java */
// 从configuration Map mappedStatements,根据获取id获取MappedStatement;
public MappedStatement getMappedStatement(String id) {
	return this.getMappedStatement(id, true);
}

public MappedStatement getMappedStatement(String id, boolean validateIncompleteStatements) {
	if (validateIncompleteStatements) {
	  buildAllStatements();
	}
	return mappedStatements.get(id);
}

// 解析缓存中未处理的statement nodes,提供fail-fast statement验证
protected void buildAllStatements() {
	if (!incompleteResultMaps.isEmpty()) {
	  synchronized (incompleteResultMaps) {
		// This always throws a BuilderException.
		incompleteResultMaps.iterator().next().resolve();
	  }
	}
	if (!incompleteCacheRefs.isEmpty()) {
	  synchronized (incompleteCacheRefs) {
		// This always throws a BuilderException.
		incompleteCacheRefs.iterator().next().resolveCacheRef();
	  }
	}
	if (!incompleteStatements.isEmpty()) {
	  synchronized (incompleteStatements) {
		// This always throws a BuilderException.
		incompleteStatements.iterator().next().parseStatementNode();
	  }
	}
	if (!incompleteMethods.isEmpty()) {
	  synchronized (incompleteMethods) {
		// This always throws a BuilderException.
		incompleteMethods.iterator().next().resolve();
	  }
	}
}

/** DefaultSqlSession.java */
// 对Collection、List、Array进行StrictMap的wrap处理
private Object wrapCollection(final Object object) {
	if (object instanceof Collection) {
	  StrictMap map = new StrictMap();
	  map.put("collection", object);
	  if (object instanceof List) {
		map.put("list", object);
	  }
	  return map;
	} else if (object != null && object.getClass().isArray()) {
	  StrictMap map = new StrictMap();
	  map.put("array", object);
	  return map;
	}
	return object;
}

/** CachingExecutor.java */
// CachingExecutor update
public int update(MappedStatement ms, Object parameterObject) throws SQLException {
	flushCacheIfRequired(ms);
	return delegate.update(ms, parameterObject);
}

// flush MappedStatement cache
private void flushCacheIfRequired(MappedStatement ms) {
	Cache cache = ms.getCache();
	if (cache != null && ms.isFlushCacheRequired()) {      
	  tcm.clear(cache);
	}
}

/** TransactionalCacheManager.java */
public void clear(Cache cache) {
	getTransactionalCache(cache).clear();
}

private TransactionalCache getTransactionalCache(Cache cache) {
	TransactionalCache txCache = transactionalCaches.get(cache);
	if (txCache == null) {
	  txCache = new TransactionalCache(cache);
	  transactionalCaches.put(cache, txCache);
	}
	return txCache;
}

/** TransactionalCache.java */
public void clear() {
	clearOnCommit = true;
	entriesToAddOnCommit.clear();
}

/** BaseExecutor.java(SimpleExecutor) */
public int update(MappedStatement ms, Object parameter) throws SQLException {
	ErrorContext.instance().resource(ms.getResource()).activity("executing an update").object(ms.getId());
	if (closed) {
	  throw new ExecutorException("Executor was closed.");
	}
	// 清空BaseExecutor下的localCache、localOutputParameterCache,其均为PerpetualCache
	// PerpetualCache实际缓存为HashMap
	clearLocalCache();
	return doUpdate(ms, parameter);
}

public void clearLocalCache() {
	if (!closed) {
	  localCache.clear();
	  localOutputParameterCache.clear();
	}
}

/** SimpleExecutor.java */
// 实际处理update请求
public int doUpdate(MappedStatement ms, Object parameter) throws SQLException {
	Statement stmt = null;
	try {
	  // 获取MappedStatement的Configuration
	  Configuration configuration = ms.getConfiguration();
	  // 创建StatementHandler
	  StatementHandler handler = configuration.newStatementHandler(this, ms, parameter, RowBounds.DEFAULT, null, null);
	  stmt = prepareStatement(handler, ms.getStatementLog());
	  return handler.update(stmt);
	} finally {
	  closeStatement(stmt);
	}
}

/** Configuration.java */
public StatementHandler newStatementHandler(Executor executor, MappedStatement mappedStatement, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) {
	StatementHandler statementHandler = new RoutingStatementHandler(executor, mappedStatement, parameterObject, rowBounds, resultHandler, boundSql);
	statementHandler = (StatementHandler) interceptorChain.pluginAll(statementHandler);
	return statementHandler;
}

/** RoutingStatementHandler.java */
// RoutingStatementHandler采用静态代理机制
// 对SimpleStatementHandler、PreparedStatementHandler、CallableStatementHandler进行代理
public RoutingStatementHandler(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) {

	switch (ms.getStatementType()) {
	  case STATEMENT:
		delegate = new SimpleStatementHandler(executor, ms, parameter, rowBounds, resultHandler, boundSql);
		break;
	  case PREPARED:
		delegate = new PreparedStatementHandler(executor, ms, parameter, rowBounds, resultHandler, boundSql);
		break;
	  case CALLABLE:
		delegate = new CallableStatementHandler(executor, ms, parameter, rowBounds, resultHandler, boundSql);
		break;
	  default:
		throw new ExecutorException("Unknown statement type: " + ms.getStatementType());
	}

}

/** PreparedStatementHandler.java */
// 创建PreparedStatementHandler
public PreparedStatementHandler(Executor executor, MappedStatement mappedStatement, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) {
	// 进入BaseStatementHandler
	super(executor, mappedStatement, parameter, rowBounds, resultHandler, boundSql);
}

/** BaseStatementHandler.java */
// BaseStatementHandler构造函数
protected BaseStatementHandler(Executor executor, MappedStatement mappedStatement, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) {
	// 用mappedStatement的configuration设置configuration属性
	this.configuration = mappedStatement.getConfiguration();
	// 设置executor属性,用于获取sql connection
	this.executor = executor;
	// 设置mappedStatement属性,用于获取boundSql
	this.mappedStatement = mappedStatement;
	// 设置rowBounds属性,用于限定获取表中记录的行数offset、limit
	this.rowBounds = rowBounds;

	// 设置typeHandlerRegistry属性,用于获取typeHandler,映射java type——jdbc type
	this.typeHandlerRegistry = configuration.getTypeHandlerRegistry();
	// 设置objectFactory属性
	this.objectFactory = configuration.getObjectFactory();

	if (boundSql == null) { // issue #435, get the key before calculating the statement
	  generateKeys(parameterObject);
	  // mappedStatement基于输入参数parameterObject创建BoundSql
	  // 实际是利用sqlSource属性创建的
	  boundSql = mappedStatement.getBoundSql(parameterObject);
	}

	this.boundSql = boundSql;

	// 构建parameterHandler,用于设置PreparedStatement的参数
	this.parameterHandler = configuration.newParameterHandler(mappedStatement, parameterObject, boundSql);
	// 构建resultSetHandler,用于处理结果集和输出参数
	this.resultSetHandler = configuration.newResultSetHandler(executor, mappedStatement, rowBounds, parameterHandler, resultHandler, boundSql);
}

/** MappedStatement.java */
public BoundSql getBoundSql(Object parameterObject) {
	// sqlSource创建BoundSql
	BoundSql boundSql = sqlSource.getBoundSql(parameterObject);
	List parameterMappings = boundSql.getParameterMappings();
	if (parameterMappings == null || parameterMappings.isEmpty()) {
	  boundSql = new BoundSql(configuration, boundSql.getSql(), parameterMap.getParameterMappings(), parameterObject);
	}

	// check for nested result maps in parameter mappings (issue #30)
	// 确定hasNestedResultMaps
	for (ParameterMapping pm : boundSql.getParameterMappings()) {
	  String rmId = pm.getResultMapId();
	  if (rmId != null) {
		ResultMap rm = configuration.getResultMap(rmId);
		if (rm != null) {
		  hasNestedResultMaps |= rm.hasNestedResultMaps();
		}
	  }
	}

	return boundSql;
}

/** RawSqlSource.java */
public BoundSql getBoundSql(Object parameterObject) {
	return sqlSource.getBoundSql(parameterObject);
}

/** StaticSqlSource.java */
public BoundSql getBoundSql(Object parameterObject) {
	return new BoundSql(configuration, sql, parameterMappings, parameterObject);
}

/** BoundSql.java */
public BoundSql(Configuration configuration, String sql, List parameterMappings, Object parameterObject) {
	this.sql = sql;
	this.parameterMappings = parameterMappings;
	this.parameterObject = parameterObject;
	this.additionalParameters = new HashMap();
	this.metaParameters = configuration.newMetaObject(additionalParameters);
}

/** Configuration.java */
// 用LanguageDriver创建ParameterHandler
public ParameterHandler newParameterHandler(MappedStatement mappedStatement, Object parameterObject, BoundSql boundSql) {
	ParameterHandler parameterHandler = mappedStatement.getLang().createParameterHandler(mappedStatement, parameterObject, boundSql);
	parameterHandler = (ParameterHandler) interceptorChain.pluginAll(parameterHandler);
	return parameterHandler;
}

/** XMLLanguageDriver.java */
public ParameterHandler createParameterHandler(MappedStatement mappedStatement, Object parameterObject, BoundSql boundSql) {
	return new DefaultParameterHandler(mappedStatement, parameterObject, boundSql);
}

/** DefaultParameterHandler.java */
public DefaultParameterHandler(MappedStatement mappedStatement, Object parameterObject, BoundSql boundSql) {
	this.mappedStatement = mappedStatement;
	this.configuration = mappedStatement.getConfiguration();
	this.typeHandlerRegistry = mappedStatement.getConfiguration().getTypeHandlerRegistry();
	this.parameterObject = parameterObject;
	this.boundSql = boundSql;
}

/** Configuration.java */
// 构建DefaultResultSetHandler
public ResultSetHandler newResultSetHandler(Executor executor, MappedStatement mappedStatement, RowBounds rowBounds, ParameterHandler parameterHandler,
  ResultHandler resultHandler, BoundSql boundSql) {
	ResultSetHandler resultSetHandler = new DefaultResultSetHandler(executor, mappedStatement, parameterHandler, resultHandler, boundSql, rowBounds);
	resultSetHandler = (ResultSetHandler) interceptorChain.pluginAll(resultSetHandler);
	return resultSetHandler;
}

/** DefaultResultSetHandler.java */
public DefaultResultSetHandler(Executor executor, MappedStatement mappedStatement, ParameterHandler parameterHandler, ResultHandler resultHandler, BoundSql boundSql,
  RowBounds rowBounds) {
	this.executor = executor;
	this.configuration = mappedStatement.getConfiguration();
	this.mappedStatement = mappedStatement;
	this.rowBounds = rowBounds;
	this.parameterHandler = parameterHandler;
	this.boundSql = boundSql;
	this.typeHandlerRegistry = configuration.getTypeHandlerRegistry();
	this.objectFactory = configuration.getObjectFactory();
	this.reflectorFactory = configuration.getReflectorFactory();
	this.resultHandler = resultHandler;
}

/** SimpleExecutor.java */
private Statement prepareStatement(StatementHandler handler, Log statementLog) throws SQLException {
	Statement stmt;
	Connection connection = getConnection(statementLog);
	stmt = handler.prepare(connection);
	handler.parameterize(stmt);
	return stmt;
}

/** BaseExecutor.java */
// BaseExecutor获取Connection,实际用transaction来获取Connection
protected Connection getConnection(Log statementLog) throws SQLException {
	Connection connection = transaction.getConnection();
	if (statementLog.isDebugEnabled()) {
	  return ConnectionLogger.newInstance(connection, statementLog, queryStack);
	} else {
	  return connection;
	}
}

/** SpringManagedTransaction.java */
public Connection getConnection() throws SQLException {
	if (this.connection == null) {
	  openConnection();
	}
	return this.connection;
}

// SpringManagedTransaction中新建sql connection
private void openConnection() throws SQLException {
	this.connection = DataSourceUtils.getConnection(this.dataSource);
	this.autoCommit = this.connection.getAutoCommit();
	this.isConnectionTransactional = DataSourceUtils.isConnectionTransactional(this.connection, this.dataSource);

	if (LOGGER.isDebugEnabled()) {
	  LOGGER.debug(
		  "JDBC Connection ["
			  + this.connection
			  + "] will"
			  + (this.isConnectionTransactional ? " " : " not ")
			  + "be managed by Spring");
	}
}

/** org.springframework.jdbc.datasource.DataSourceUtils.java */
public static Connection getConnection(DataSource dataSource) throws CannotGetJdbcConnectionException {
	try {
		return doGetConnection(dataSource);
	}
	catch (SQLException ex) {
		throw new CannotGetJdbcConnectionException("Could not get JDBC Connection", ex);
	}
}

public static Connection doGetConnection(DataSource dataSource) throws SQLException {
	Assert.notNull(dataSource, "No DataSource specified");

	// 先从TransactionSynchronizationManager的事务资源缓存resources获取dataSource对应的conHolder
	ConnectionHolder conHolder = (ConnectionHolder) TransactionSynchronizationManager.getResource(dataSource);
	if (conHolder != null && (conHolder.hasConnection() || conHolder.isSynchronizedWithTransaction())) {
		// TransactionSynchronizationManager的事务资源缓存中有conHolder,则直接返回Connection
		conHolder.requested();
		if (!conHolder.hasConnection()) {
			logger.debug("Fetching resumed JDBC Connection from DataSource");
			conHolder.setConnection(dataSource.getConnection());
		}
		return conHolder.getConnection();
	}
	// Else we either got no holder or an empty thread-bound holder here.

	logger.debug("Fetching JDBC Connection from DataSource");
	// 从DataSource获取JDBC Connection
	Connection con = dataSource.getConnection();

	if (TransactionSynchronizationManager.isSynchronizationActive()) {
		// 为JDBC Connection注册Transaction synchronizations
		logger.debug("Registering transaction synchronization for JDBC Connection");
		// Use same Connection for further JDBC actions within the transaction.
		// Thread-bound object will get removed by synchronization at transaction completion.
		ConnectionHolder holderToUse = conHolder;
		if (holderToUse == null) {
			holderToUse = new ConnectionHolder(con);
		}
		else {
			holderToUse.setConnection(con);
		}
		holderToUse.requested();
		TransactionSynchronizationManager.registerSynchronization(
				new ConnectionSynchronization(holderToUse, dataSource));
		holderToUse.setSynchronizedWithTransaction(true);
		if (holderToUse != conHolder) {
			// 绑定Transactional resources
			TransactionSynchronizationManager.bindResource(dataSource, holderToUse);
		}
	}

	return con;
}

/** ConnectionHolder.java */
protected boolean hasConnection() {
	return (this.connectionHandle != null);
}

public Connection getConnection() {
	Assert.notNull(this.connectionHandle, "Active Connection is required");
	if (this.currentConnection == null) {
		this.currentConnection = this.connectionHandle.getConnection();
	}
	return this.currentConnection;
}

/** DataSourceUtils.java */
// 判断con是否来自TransactionSynchronizationManager中resources的key为dataSource的conHolder的Connection
public static boolean isConnectionTransactional(Connection con, DataSource dataSource) {
	if (dataSource == null) {
		return false;
	}
	ConnectionHolder conHolder = (ConnectionHolder) TransactionSynchronizationManager.getResource(dataSource);
	return (conHolder != null && connectionEquals(conHolder, con));
}

private static boolean connectionEquals(ConnectionHolder conHolder, Connection passedInCon) {
	if (!conHolder.hasConnection()) {
		return false;
	}
	Connection heldCon = conHolder.getConnection();
	// Explicitly check for identity too: for Connection handles that do not implement
	// "equals" properly, such as the ones Commons DBCP exposes).
	return (heldCon == passedInCon || heldCon.equals(passedInCon) ||
			getTargetConnection(heldCon).equals(passedInCon));
}

/** ConnectionLogger.java */
public static Connection newInstance(Connection conn, Log statementLog, int queryStack) {
	InvocationHandler handler = new ConnectionLogger(conn, statementLog, queryStack);
	ClassLoader cl = Connection.class.getClassLoader();
	return (Connection) Proxy.newProxyInstance(cl, new Class[]{Connection.class}, handler);
}

/** RoutingStatementHandler.java */
public Statement prepare(Connection connection) throws SQLException {
	return delegate.prepare(connection);
}

/** BaseStatementHandler.java */
// 用connection.prepareStatement获取预编译的PreparedStatement
// 且设置其queryTimeout、fetchSize属性
public Statement prepare(Connection connection) throws SQLException {
	ErrorContext.instance().sql(boundSql.getSql());
	Statement statement = null;
	try {
	  // 用connection获取PreparedStatement
	  statement = instantiateStatement(connection);
	  // 用mappedStatement的queryTimeout属性设置statement的queryTimeout
	  setStatementTimeout(statement);
	  // 用mappedStatement的fetchSize属性设置statement的fetchSize
	  setFetchSize(statement);
	  return statement;
	} catch (SQLException e) {
	  closeStatement(statement);
	  throw e;
	} catch (Exception e) {
	  closeStatement(statement);
	  throw new ExecutorException("Error preparing statement.  Cause: " + e, e);
	}
}

/** PreparedStatementHandler.java */
// connection.prepareStatement,获取预编译的sql语句,PreparedStatement
protected Statement instantiateStatement(Connection connection) throws SQLException {
	String sql = boundSql.getSql();
	if (mappedStatement.getKeyGenerator() instanceof Jdbc3KeyGenerator) {
	  String[] keyColumnNames = mappedStatement.getKeyColumns();
	  if (keyColumnNames == null) {
		return connection.prepareStatement(sql, PreparedStatement.RETURN_GENERATED_KEYS);
	  } else {
		return connection.prepareStatement(sql, keyColumnNames);
	  }
	} else if (mappedStatement.getResultSetType() != null) {
	  return connection.prepareStatement(sql, mappedStatement.getResultSetType().getValue(), ResultSet.CONCUR_READ_ONLY);
	} else {
	  return connection.prepareStatement(sql);
	}
}

/** BaseStatementHandler.java */
protected void setStatementTimeout(Statement stmt) throws SQLException {
	Integer timeout = mappedStatement.getTimeout();
	Integer defaultTimeout = configuration.getDefaultStatementTimeout();
	if (timeout != null) {
	  stmt.setQueryTimeout(timeout);
	} else if (defaultTimeout != null) {
	  stmt.setQueryTimeout(defaultTimeout);
	}
}

protected void setFetchSize(Statement stmt) throws SQLException {
	Integer fetchSize = mappedStatement.getFetchSize();
	if (fetchSize != null) {
	  stmt.setFetchSize(fetchSize);
	  return;
	}
	Integer defaultFetchSize = configuration.getDefaultFetchSize();
	if (defaultFetchSize != null) {
	  stmt.setFetchSize(defaultFetchSize);
	}
}

/** RoutingStatementHandler.java */
public void parameterize(Statement statement) throws SQLException {
	delegate.parameterize(statement);
}

/** PreparedStatementHandler.java */
public void parameterize(Statement statement) throws SQLException {
	parameterHandler.setParameters((PreparedStatement) statement);
}

/** DefaultParameterHandler.java */
// PreparedStatement设置占位符参数值
public void setParameters(PreparedStatement ps) {
	ErrorContext.instance().activity("setting parameters").object(mappedStatement.getParameterMap().getId());
	List parameterMappings = boundSql.getParameterMappings();
	if (parameterMappings != null) {
	  for (int i = 0; i < parameterMappings.size(); i++) {
		ParameterMapping parameterMapping = parameterMappings.get(i);
		if (parameterMapping.getMode() != ParameterMode.OUT) {
		  Object value;
		  // 获取参数名称
		  String propertyName = parameterMapping.getProperty();
		  if (boundSql.hasAdditionalParameter(propertyName)) { // issue #448 ask first for additional params
			value = boundSql.getAdditionalParameter(propertyName);
		  } else if (parameterObject == null) {
			value = null;
		  } else if (typeHandlerRegistry.hasTypeHandler(parameterObject.getClass())) {
			value = parameterObject;
		  } else {
			MetaObject metaObject = configuration.newMetaObject(parameterObject);
			// 获取参数值
			value = metaObject.getValue(propertyName);
		  }
		  TypeHandler typeHandler = parameterMapping.getTypeHandler();
		  JdbcType jdbcType = parameterMapping.getJdbcType();
		  if (value == null && jdbcType == null) {
			jdbcType = configuration.getJdbcTypeForNull();
		  }
		  try {
			// 采用匹配value, jdbcType类型的typeHandler,便于PreparedStatement设置占位符参数值
			typeHandler.setParameter(ps, i + 1, value, jdbcType);
		  } catch (TypeException e) {
			throw new TypeException("Could not set parameters for mapping: " + parameterMapping + ". Cause: " + e, e);
		  } catch (SQLException e) {
			throw new TypeException("Could not set parameters for mapping: " + parameterMapping + ". Cause: " + e, e);
		  }
		}
	  }
	}
}

/** BaseTypeHandler.java */
public void setParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType) throws SQLException {
	if (parameter == null) {
	  if (jdbcType == null) {
		throw new TypeException("JDBC requires that the JdbcType must be specified for all nullable parameters.");
	  }
	  try {
		ps.setNull(i, jdbcType.TYPE_CODE);
	  } catch (SQLException e) {
		throw new TypeException("Error setting null for parameter #" + i + " with JdbcType " + jdbcType + " . " +
				"Try setting a different JdbcType for this parameter or a different jdbcTypeForNull configuration property. " +
				"Cause: " + e, e);
	  }
	} else {
	  try {
		setNonNullParameter(ps, i, parameter, jdbcType);
	  } catch (Exception e) {
		throw new TypeException("Error setting non null for parameter #" + i + " with JdbcType " + jdbcType + " . " +
				"Try setting a different JdbcType for this parameter or a different configuration property. " +
				"Cause: " + e, e);
	  }
	}
}

/** UnknownTypeHandler.java */
public void setNonNullParameter(PreparedStatement ps, int i, Object parameter, JdbcType jdbcType)
  throws SQLException {
	// 基于value, jdbcType类型获取匹配的typeHandler
	TypeHandler handler = resolveTypeHandler(parameter, jdbcType);
	// PreparedStatement设置占位符参数值
	handler.setParameter(ps, i, parameter, jdbcType);
}

private TypeHandler resolveTypeHandler(Object parameter, JdbcType jdbcType) {
	TypeHandler handler;
	if (parameter == null) {
	  handler = OBJECT_TYPE_HANDLER;
	} else {
	  handler = typeHandlerRegistry.getTypeHandler(parameter.getClass(), jdbcType);
	  // check if handler is null (issue #270)
	  if (handler == null || handler instanceof UnknownTypeHandler) {
		handler = OBJECT_TYPE_HANDLER;
	  }
	}
	return handler;
}

/** TypeHandlerRegistry.java */
public  TypeHandler getTypeHandler(Class type, JdbcType jdbcType) {
	return getTypeHandler((Type) type, jdbcType);
}

private  TypeHandler getTypeHandler(Type type, JdbcType jdbcType) {
	Map> jdbcHandlerMap = TYPE_HANDLER_MAP.get(type);
	TypeHandler handler = null;
	if (jdbcHandlerMap != null) {
	  handler = jdbcHandlerMap.get(jdbcType);
	  if (handler == null) {
		handler = jdbcHandlerMap.get(null);
	  }
	}
	if (handler == null && type != null && type instanceof Class && Enum.class.isAssignableFrom((Class) type)) {
	  handler = new EnumTypeHandler((Class) type);
	}
	// type drives generics here
	return (TypeHandler) handler;
}

/** StringTypeHandler.java */
public void setNonNullParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType)
  throws SQLException {
	ps.setString(i, parameter);
}

/** RoutingStatementHandler.java */
public int update(Statement statement) throws SQLException {
	return delegate.update(statement);
}

/** PreparedStatementHandler.java */
// 真正执行PreparedStatement
public int update(Statement statement) throws SQLException {
	PreparedStatement ps = (PreparedStatement) statement;
	// 执行PreparedStatement
	ps.execute();
	// 获取写的记录行数
	int rows = ps.getUpdateCount();
	Object parameterObject = boundSql.getParameterObject();
	KeyGenerator keyGenerator = mappedStatement.getKeyGenerator();
	keyGenerator.processAfter(executor, mappedStatement, ps, parameterObject);
	return rows;
}

/** SqlSessionUtils.java */
// 用session与Transactional resources的sessionFactory所关联的SqlSessionHolder的SqlSession进行比较
// 判断是否为Spring transactional
public static boolean isSqlSessionTransactional(SqlSession session, SqlSessionFactory sessionFactory) {
	notNull(session, NO_SQL_SESSION_SPECIFIED);
	notNull(sessionFactory, NO_SQL_SESSION_FACTORY_SPECIFIED);

	SqlSessionHolder holder = (SqlSessionHolder) TransactionSynchronizationManager.getResource(sessionFactory);

	return (holder != null) && (holder.getSqlSession() == session);
} 
  

你可能感兴趣的:(mybatis)