【工具型框架】Mybatis——四大对象原理/扩展

四大对象原理——SQL调用阶段

【工具型框架】Mybatis——四大对象原理/扩展_第1张图片

Executor

DefaultSqlSession 封装了大部分跟数据库交互细节,因此通过分析这个类我们可以获知很多东西
外部看,Executor是完成事务以及回滚和执行sql的关键

public class DefaultSqlSession implements SqlSession {
     
    private final Configuration configuration;
    private final Executor executor;
    private final boolean autoCommit;
    private boolean dirty;
    private List<Cursor<?>> cursorList;
    public DefaultSqlSession(Configuration configuration, Executor executor, boolean autoCommit) {
     
        this.configuration = configuration;
        this.executor = executor;
        this.dirty = false;
        this.autoCommit = autoCommit;
    }

    public DefaultSqlSession(Configuration configuration, Executor executor) {
     
        this(configuration, executor, false);
    }

    @Override
    public void commit() {
     
        commit(false);
    }
    @Override
    public void commit(boolean force) {
     
        try {
     
            executor.commit(isCommitOrRollbackRequired(force));
            dirty = false;
        } catch (Exception e) {
     
            throw ExceptionFactory.wrapException("Error committing transaction.  Cause: " + e, e);
        } finally {
     
            ErrorContext.instance().reset();
        }
    }

    @Override
    public void rollback() {
     
        rollback(false);
    }

    @Override
    public void rollback(boolean force) {
     
        try {
     
            executor.rollback(isCommitOrRollbackRequired(force));
            dirty = false;
        } catch (Exception e) {
     
            throw ExceptionFactory.wrapException("Error rolling back transaction.  Cause: " + e, e);
        } finally {
     
            ErrorContext.instance().reset();
        }
    }

    @Override
    public List<BatchResult> flushStatements() {
     
        try {
     
            return executor.flushStatements();
        } catch (Exception e) {
     
            throw ExceptionFactory.wrapException("Error flushing statements.  Cause: " + e, e);
        } finally {
     
            ErrorContext.instance().reset();
        }
    }

    @Override
    public void close() {
     
        try {
     
            executor.close(isCommitOrRollbackRequired(false));
            closeCursors();
            dirty = false;
        } finally {
     
            ErrorContext.instance().reset();
        }
    }
}

实现类
【工具型框架】Mybatis——四大对象原理/扩展_第2张图片
BaseExecutor

基础实现,是一个抽象类,主要是实现了一些事物的基本功能,还有一些参数缓存等等

SimpleExecutor

一个子类,主要定义doUpdate、doFlushStatements、doQuery、doQueryCursor

public class SimpleExecutor extends BaseExecutor {
     

  public SimpleExecutor(Configuration configuration, Transaction transaction) {
     
    super(configuration, transaction);
  }

  /*
    更新
    传入语句和参数,调用处理器完成处理
   */
  public <E> List<E> doQuery(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) throws SQLException {
     
    Statement stmt = null;
    try {
     
      Configuration configuration = ms.getConfiguration();
      /*
        返回一个语句处理器,利用插件
       */
      StatementHandler handler = configuration.newStatementHandler(wrapper, ms, parameter, rowBounds, resultHandler, boundSql);
      /*
        处理语句
       */
      stmt = prepareStatement(handler, ms.getStatementLog());
       /*
       利用hadler发起请求
       */
      return handler.query(stmt, resultHandler);
    } finally {
     
      closeStatement(stmt);
    }
  }
   /*
        处理语句
     */
   private Statement prepareStatement(StatementHandler handler, Log statementLog) throws SQLException {
     
    Statement stmt;
    Connection connection = getConnection(statementLog);
     /* 
      语句安全的处理,比如超时时间之类的
     */
    stmt = handler.prepare(connection, transaction.getTimeout());
    /* 
      语句参数的处理
     */
    handler.parameterize(stmt);
    return stmt;
  }

StatementHandler——SQL生成处理/执行代码/结果处理

BaseStatementHandler

内置ParameterHandler、DefaultParameterHandler;这两个组件实现功能
StatementHandler实现流程,mybatis StatementHandler的实现类主要就是继承这个

public abstract class BaseStatementHandler implements StatementHandler {
     
  protected final Configuration configuration;
  protected final ObjectFactory objectFactory;
  protected final TypeHandlerRegistry typeHandlerRegistry;
  protected final ResultSetHandler resultSetHandler;
  protected final ParameterHandler parameterHandler;


   public Statement prepare(Connection connection, Integer transactionTimeout) throws SQLException {
     
    ErrorContext.instance().sql(boundSql.getSql());
    Statement statement = null;
    try {
     
      statement = instantiateStatement(connection);
      setStatementTimeout(statement, transactionTimeout);
      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);
    }
  }

}

四大对象原理——SQL处理阶段

ParameterHandler——处理SQL的参数对象

PreparedStatementHandler——语句准备处理器

 public class PreparedStatementHandler extends BaseStatementHandler {
     
  public void parameterize(Statement statement) throws SQLException {
     
    parameterHandler.setParameters((PreparedStatement) statement);
  }
 }

DefaultParameterHandler——参数处理器

 public class DefaultParameterHandler implements ParameterHandler {
     
   /*
     利用类型匹配进行value和语句的值对应
    */
   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 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();
          }
          /*
             调用typeHandler完成最终匹配
          */
          try {
     
            typeHandler.setParameter(ps, i + 1, value, jdbcType);
          } catch (TypeException | SQLException e) {
     
            throw new TypeException("Could not set parameters for mapping: " + parameterMapping + ". Cause: " + e, e);
          }
        }
      }
    }
  }
}

ResultHandler——处理SQL的返回结果集

public interface ResultSet extends Wrapper, AutoCloseable {
     
	int getInt(int columnIndex);
	int getInt(String columnLabel);
	String getString(int columnIndex);
	String getString(String columnLabel) ;
}

columnIndex:一行结果集中字段下标
columnLabel:一行结果集中字段key

【工具型框架】Mybatis——四大对象原理/扩展_第3张图片
DefaultResultSetHandler

public class DefaultResultSetHandler implements ResultSetHandler {
     
 /*
   handleResultSets:处理批量结果,主要看他怎么调用handleResultSet
  */ 
 public List<Object> handleResultSets(Statement stmt) throws SQLException {
     
    ErrorContext.instance().activity("handling results").object(mappedStatement.getId());
    final List<Object> multipleResults = new ArrayList<>();
    int resultSetCount = 0;
    ResultSetWrapper rsw = getFirstResultSet(stmt);
    /*
     获取结果映射map
     */
    List<ResultMap> resultMaps = mappedStatement.getResultMaps();
    int resultMapCount = resultMaps.size();
    validateResultMapsCount(rsw, resultMapCount);//校验结果书看了
    while (rsw != null && resultMapCount > resultSetCount) {
     
      ResultMap resultMap = resultMaps.get(resultSetCount);
      handleResultSet(rsw, resultMap, multipleResults, null);
      rsw = getNextResultSet(stmt);
      cleanUpAfterHandlingResultSet();
      resultSetCount++;
    }
    String[] resultSets = mappedStatement.getResultSets();
    if (resultSets != null) {
     
      while (rsw != null && resultSetCount < resultSets.length) {
     
        ResultMapping parentMapping = nextResultMaps.get(resultSets[resultSetCount]);
        if (parentMapping != null) {
     
          String nestedResultMapId = parentMapping.getNestedResultMapId();
          ResultMap resultMap = configuration.getResultMap(nestedResultMapId);
          handleResultSet(rsw, resultMap, null, parentMapping);
        }
        rsw = getNextResultSet(stmt);
        cleanUpAfterHandlingResultSet();
        resultSetCount++;
      }
    }

    return collapseSingleResultList(multipleResults);
  }
 /*
   handleResultSet处理单个结果,主要看他怎么调用handleRowValues
  */ 
   private void handleResultSet(ResultSetWrapper rsw, ResultMap resultMap, List<Object> multipleResults, ResultMapping parentMapping) throws SQLException {
     
    try {
     
      if (parentMapping != null) {
     
        handleRowValues(rsw, resultMap, null, RowBounds.DEFAULT, parentMapping);
      } else {
     
        if (resultHandler == null) {
     
          DefaultResultHandler defaultResultHandler = new DefaultResultHandler(objectFactory);
          handleRowValues(rsw, resultMap, defaultResultHandler, rowBounds, null);
          multipleResults.add(defaultResultHandler.getResultList());
        } else {
     
          handleRowValues(rsw, resultMap, resultHandler, rowBounds, null);
        }
      }
    } finally {
     
      closeResultSet(rsw.getResultSet());
    }
  }
  
   /*
     针对类型做处理
     handleRowValuesForNestedResultMap、handleRowValuesForSimpleResultMap
    */
  public void handleRowValues(ResultSetWrapper rsw, ResultMap resultMap, ResultHandler<?> resultHandler, RowBounds rowBounds, ResultMapping parentMapping) throws SQLException {
     
    if (resultMap.hasNestedResultMaps()) {
     
      ensureNoRowBounds();
      checkResultHandler();
      handleRowValuesForNestedResultMap(rsw, resultMap, resultHandler, rowBounds, parentMapping);
    } else {
     
      handleRowValuesForSimpleResultMap(rsw, resultMap, resultHandler, rowBounds, parentMapping);
    }
    /*
      主要看他调用getRowValue
    */
  private void handleRowValuesForNestedResultMap(ResultSetWrapper rsw, ResultMap resultMap, ResultHandler<?> resultHandler, RowBounds rowBounds, ResultMapping parentMapping) throws SQLException {
     
    final DefaultResultContext<Object> resultContext = new DefaultResultContext<>();
    ResultSet resultSet = rsw.getResultSet();
    skipRows(resultSet, rowBounds);
    Object rowValue = previousRowValue;
    while (shouldProcessMoreRows(resultContext, rowBounds) && !resultSet.isClosed() && resultSet.next()) {
     
      final ResultMap discriminatedResultMap = resolveDiscriminatedResultMap(resultSet, resultMap, null);
      final CacheKey rowKey = createRowKey(discriminatedResultMap, rsw, null);
      Object partialObject = nestedResultObjects.get(rowKey);
      // issue #577 && #542
      if (mappedStatement.isResultOrdered()) {
     
        if (partialObject == null && rowValue != null) {
     
          nestedResultObjects.clear();
          storeObject(resultHandler, resultContext, rowValue, parentMapping, resultSet);
        }
        rowValue = getRowValue(rsw, discriminatedResultMap, rowKey, null, partialObject);
      } else {
     
        rowValue = getRowValue(rsw, discriminatedResultMap, rowKey, null, partialObject);
        if (partialObject == null) {
     
          storeObject(resultHandler, resultContext, rowValue, parentMapping, resultSet);
        }
      }
    }
  /*
    主要看他调用
    applyNestedResultMappings
    applyPropertyMappings
    shouldApplyAutomaticMappings.
    applyNestedResultMappings
    这些方法会调用typeHandler做最后的类型处理
   */
   private Object getRowValue(ResultSetWrapper rsw, ResultMap resultMap, CacheKey combinedKey, String columnPrefix, Object partialObject) throws SQLException {
     
    final String resultMapId = resultMap.getId();
    Object rowValue = partialObject;
    if (rowValue != null) {
     
      final MetaObject metaObject = configuration.newMetaObject(rowValue);
      putAncestor(rowValue, resultMapId);
      applyNestedResultMappings(rsw, resultMap, metaObject, columnPrefix, combinedKey, false);
      ancestorObjects.remove(resultMapId);
    } else {
     
      final ResultLoaderMap lazyLoader = new ResultLoaderMap();
      rowValue = createResultObject(rsw, resultMap, lazyLoader, columnPrefix);
      if (rowValue != null && !hasTypeHandlerForResultObject(rsw, resultMap.getType())) {
     
        final MetaObject metaObject = configuration.newMetaObject(rowValue);
        boolean foundValues = this.useConstructorMappings;
        if (shouldApplyAutomaticMappings(resultMap, true)) {
     
          foundValues = applyAutomaticMappings(rsw, resultMap, metaObject, columnPrefix) || foundValues;
        }
        foundValues = applyPropertyMappings(rsw, resultMap, metaObject, lazyLoader, columnPrefix) || foundValues;
        putAncestor(rowValue, resultMapId);
        foundValues = applyNestedResultMappings(rsw, resultMap, metaObject, columnPrefix, combinedKey, true) || foundValues;
        ancestorObjects.remove(resultMapId);
        foundValues = lazyLoader.size() > 0 || foundValues;
        rowValue = foundValues || configuration.isReturnInstanceForEmptyRow() ? rowValue : null;
      }
      if (combinedKey != CacheKey.NULL_CACHE_KEY) {
     
        nestedResultObjects.put(combinedKey, rowValue);
      }
    }
    return rowValue;
  }
  /*
    比如说这个调用了typeHandler
   */
  private boolean applyAutomaticMappings(ResultSetWrapper rsw, ResultMap resultMap, MetaObject metaObject, String columnPrefix) throws SQLException {
     
    List<UnMappedColumnAutoMapping> autoMapping = createAutomaticMappings(rsw, resultMap, metaObject, columnPrefix);
    boolean foundValues = false;
    if (!autoMapping.isEmpty()) {
     
      for (UnMappedColumnAutoMapping mapping : autoMapping) {
     
        final Object value = mapping.typeHandler.getResult(rsw.getResultSet(), mapping.column);
        if (value != null) {
     
          foundValues = true;
        }
        if (value != null || (configuration.isCallSettersOnNulls() && !mapping.primitive)) {
     
          // gcode issue #377, call setter on nulls (value is not 'found')
          metaObject.setValue(mapping.property, value);
        }
      }
    }
    return foundValues;
  }
}

四大对象原理——插件调用原理

上面通过插件统一返回处理器对象,这些方法都封装在了Configuration ,这些代码很明显都通过在Default的基础上,利用pluginAll返回一个插件处理后的对象,因此调用者可以在这里处理插件

public class Configuration {
     
    public LanguageDriver getDefaultScriptingLanuageInstance() {
     
    return getDefaultScriptingLanguageInstance();
  }
  public MetaObject newMetaObject(Object object) {
     
    return MetaObject.forObject(object, objectFactory, objectWrapperFactory, reflectorFactory);
  }

  public ParameterHandler newParameterHandler(MappedStatement mappedStatement, Object parameterObject, BoundSql boundSql) {
     
    ParameterHandler parameterHandler = mappedStatement.getLang().createParameterHandler(mappedStatement, parameterObject, boundSql);
    parameterHandler = (ParameterHandler) interceptorChain.pluginAll(parameterHandler);
    return parameterHandler;
  }

  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;
  }

  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;
  }
}

利用责任链返回最终的包装对象

public class InterceptorChain {
     
  private final List<Interceptor> interceptors = new ArrayList<>();
  public Object pluginAll(Object target) {
     
    for (Interceptor interceptor : interceptors) {
     
      target = interceptor.plugin(target);
    }
    return target;
  }
  public void addInterceptor(Interceptor interceptor) {
     
    interceptors.add(interceptor);
  }
  public List<Interceptor> getInterceptors() {
     
    return Collections.unmodifiableList(interceptors);
  }
}

四大对象扩展——Mybatis自定义类型处理DEMO(待)

四大对象扩展——Mybatis自定义插件扩展DEMO(待)

你可能感兴趣的:(Java框架源码,java,mybatis)