讀mybatis源碼之十一:參數處理器

主要是給聲明裏面填充參數

一、創建參數處理器

在聲明處理器基類中:
this.parameterHandler = configuration.newParameterHandler(mappedStatement, parameterObject, boundSql);
對應configuration裏面:
 public ParameterHandler newParameterHandler(MappedStatement mappedStatement, Object parameterObject, BoundSql boundSql) {
    ParameterHandler parameterHandler = mappedStatement.getLang().createParameterHandler(mappedStatement, parameterObject, boundSql);
    parameterHandler = (ParameterHandler) interceptorChain.pluginAll(parameterHandler);
    return parameterHandler;
  }
parameterHandler = (ParameterHandler) interceptorChain.pluginAll(parameterHandler);
表明在參數處理之前可以定義攔截處理

二、調用參數處理器

跟蹤進去發現createParameterHandler裏面都是使用DefaultParameterHandler這個參數處理器。
在聲明處理器中都有:
 public void parameterize(Statement statement) throws SQLException {
    parameterHandler.setParameters((PreparedStatement) statement);
  }
在執行器中有:
private Statement prepareStatement(StatementHandler handler, Log statementLog) throws SQLException {
    Statement stmt;
    Connection connection = getConnection(statementLog);
    stmt = handler.prepare(connection);
    handler.parameterize(stmt);
    return stmt;
  }
到這裏也就知道了,執行器調用聲明處理器parameterize方法,parameterize方法調用參數處理器parameterHandler填充參數

三、參數處理器如何填充參數

public void setParameters(PreparedStatement ps) throws SQLException {
    ErrorContext.instance().activity("setting parameters").object(mappedStatement.getParameterMap().getId());
    List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();
    if (parameterMappings != null) {
      MetaObject metaObject = parameterObject == null ? null : configuration.newMetaObject(parameterObject);
      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 {
            value = metaObject == null ? null : metaObject.getValue(propertyName);
          }
          TypeHandler typeHandler = parameterMapping.getTypeHandler();
          JdbcType jdbcType = parameterMapping.getJdbcType();
          if (value == null && jdbcType == null) jdbcType = configuration.getJdbcTypeForNull();
          typeHandler.setParameter(ps, i + 1, value, jdbcType);
        }
      }
    }
  }

該部分是獲取參數mapping,然後怎麼獲取字段的值,也就是說這裏都是mybatis提供的解析,如何獲取參數值,在攔截器中可以借鑑

TypeHandler 類型處理器含有org.apache.ibatis.type裏面的基礎類型處理器,還有自己註冊的類型處理器

BaseTypeHandler類型處理器基類裏面setParameter可以看到就是使用各個類型給聲明填充參數。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章