本文从源码分析的角度分析Mybatis一次insert请求处理流程。
insert整体处理流程
时序图
相关源码
/** 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工作流程
时序图
相关类结构图
SqlSession类结构图:
Executor类结构图:
Transaction类结构图:
SqlSession构建过程中的组件支持
相关源码
/** 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工作流程
时序图
相关类结构图
ObjectWrapper类结构图:
相关Handler类结构图:
TypeHandler类结构图:
Mybatis一次请求处理核心流程(select|insert|update|delete)
相关源码
/** 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 extends Object> resolveTypeHandler(Object parameter, JdbcType jdbcType) {
TypeHandler extends Object> 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);
}