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

来源:互联网 发布:微信域名案 编辑:程序博客网 时间:2024/05/17 11:56

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

insert整体处理流程

时序图


相关源码

/** SqlSessionTemplate.java */public int insert(String statement, Object parameter) {return this.sqlSessionProxy.insert(statement, parameter);}// jdk动态代理private class SqlSessionInterceptor implements InvocationHandler {@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {// 获取SqlSessionSqlSession 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对应的SqlSessionHolderSqlSessionHolder holder = (SqlSessionHolder) TransactionSynchronizationManager.getResource(sessionFactory);// 从SqlSessionHolder中提取SqlSessionSqlSession session = sessionHolder(executorType, holder);if (session != null) {  return session;}if (LOGGER.isDebugEnabled()) {  LOGGER.debug("Creating a new SqlSession");}// 打开新的SqlSessionsession = 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<Map<Object, Object>> resources获取actualKey对应的资源// ThreadLocal模式,线程安全private static Object doGetResource(Object actualKey) {Map<Object, Object> 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获取TransactionFactoryprivate TransactionFactory getTransactionFactoryFromEnvironment(Environment environment) {if (environment == null || environment.getTransactionFactory() == null) {  // 默认为ManagedTransactionFactory  return new ManagedTransactionFactory();}return environment.getTransactionFactory();}/** SpringManagedTransactionFactory.java */// Spring容器管理下的transactionpublic 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 + "]");}// 构建SqlSessionHolderholder = new SqlSessionHolder(session, executorType, exceptionTranslator);// Transactional resources添加sessionFactory、holder键值对,resources为ThreadLocal<Map<Object, Object>>TransactionSynchronizationManager.bindResource(sessionFactory, holder);// Transaction synchronizations添加SqlSessionSynchronization,synchronizations为ThreadLocal<Set<TransactionSynchronization>>TransactionSynchronizationManager.registerSynchronization(new SqlSessionSynchronization(holder, sessionFactory));holder.setSynchronizedWithTransaction(true); // holder标识synchronizedWithTransaction为trueholder.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、deletepublic 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<String, MappedStatement> 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<Object> map = new StrictMap<Object>();  map.put("collection", object);  if (object instanceof List) {map.put("list", object);  }  return map;} else if (object != null && object.getClass().isArray()) {  StrictMap<Object> map = new StrictMap<Object>();  map.put("array", object);  return map;}return object;}/** CachingExecutor.java */// CachingExecutor updatepublic int update(MappedStatement ms, Object parameterObject) throws SQLException {flushCacheIfRequired(ms);return delegate.update(ms, parameterObject);}// flush MappedStatement cacheprivate 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<Object, Object>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 */// 创建PreparedStatementHandlerpublic PreparedStatementHandler(Executor executor, MappedStatement mappedStatement, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) {// 进入BaseStatementHandlersuper(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 connectionthis.executor = executor;// 设置mappedStatement属性,用于获取boundSqlthis.mappedStatement = mappedStatement;// 设置rowBounds属性,用于限定获取表中记录的行数offset、limitthis.rowBounds = rowBounds;// 设置typeHandlerRegistry属性,用于获取typeHandler,映射java type——jdbc typethis.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创建BoundSqlBoundSql boundSql = sqlSource.getBoundSql(parameterObject);List<ParameterMapping> 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)// 确定hasNestedResultMapsfor (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<ParameterMapping> parameterMappings, Object parameterObject) {this.sql = sql;this.parameterMappings = parameterMappings;this.parameterObject = parameterObject;this.additionalParameters = new HashMap<String, Object>();this.metaParameters = configuration.newMetaObject(additionalParameters);}/** Configuration.java */// 用LanguageDriver创建ParameterHandlerpublic 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 */// 构建DefaultResultSetHandlerpublic 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来获取Connectionprotected 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 connectionprivate 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对应的conHolderConnectionHolder conHolder = (ConnectionHolder) TransactionSynchronizationManager.getResource(dataSource);if (conHolder != null && (conHolder.hasConnection() || conHolder.isSynchronizedWithTransaction())) {// TransactionSynchronizationManager的事务资源缓存中有conHolder,则直接返回ConnectionconHolder.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 ConnectionConnection con = dataSource.getConnection();if (TransactionSynchronizationManager.isSynchronizationActive()) {// 为JDBC Connection注册Transaction synchronizationslogger.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 resourcesTransactionSynchronizationManager.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的Connectionpublic 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语句,PreparedStatementprotected 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<ParameterMapping> 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 paramsvalue = 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类型获取匹配的typeHandlerTypeHandler 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 <T> TypeHandler<T> getTypeHandler(Class<T> type, JdbcType jdbcType) {return getTypeHandler((Type) type, jdbcType);}private <T> TypeHandler<T> getTypeHandler(Type type, JdbcType jdbcType) {Map<JdbcType, TypeHandler<?>> 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 herereturn (TypeHandler<T>) 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 */// 真正执行PreparedStatementpublic int update(Statement statement) throws SQLException {PreparedStatement ps = (PreparedStatement) statement;// 执行PreparedStatementps.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 transactionalpublic 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);}

0 0
原创粉丝点击