java executor包參數處理功能 

sql語句中的參數賦值是有由executor包中的parameter子包完成的。

parameter子包其實隻有一個parameterHandler接口,它定義瞭2個方法:

public interface ParameterHandler {

  Object getParameterObject();

  void setParameters(PreparedStatement ps)
      throws SQLException;

}

ParameterHandler接口有一個默認的實現類DefaultParameterHandler,它在scripting包的子包中。

mybatis中支持進行參數設置的語句類型是PreparedStatement接口及其子接口CallableStatement, 所以setParameters的輸入參數是PreparedStatement類型。

setParameters方法的實現邏輯就是依次取出每個參數的值,然後根據參數類型調用PreparedStatement中的賦值方法進行賦值。

public class DefaultParameterHandler implements ParameterHandler {
  // 類型處理器註冊表
  private final TypeHandlerRegistry typeHandlerRegistry;
  // MappedStatement對象(包含完整的增刪改查節點信息)
  private final MappedStatement mappedStatement;
  // 參數對象
  private final Object parameterObject;
  // BoundSql對象(包含SQL語句、參數、實參信息)
  private final BoundSql boundSql;
  // 配置信息
  private final Configuration configuration;

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

  @Override
  public Object getParameterObject() {
    return parameterObject;
  }

  /**
   * 為語句設置參數
   * @param ps 語句
   */
  @Override
  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);
        // ParameterMode.OUT是CallableStatement的輸出參數,已經單獨註冊。故忽略
        if (parameterMapping.getMode() != ParameterMode.OUT) {
          Object value;
          // 取出屬性名稱
          String propertyName = parameterMapping.getProperty();
          if (boundSql.hasAdditionalParameter(propertyName)) {
            // 從附加參數中讀取屬性值
            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 {
            // 此方法最終根據參數類型,調用java.sql.PreparedStatement類中的參數賦值方法,對SQL語句中的參數賦值
            typeHandler.setParameter(ps, i + 1, value, jdbcType);
          } catch (TypeException | SQLException e) {
            throw new TypeException("Could not set parameters for mapping: " + parameterMapping + ". Cause: " + e, e);
          }
        }
      }
    }
  }

}

到此這篇關於java executor包參數處理功能 的文章就介紹到這瞭,更多相關executor包參數處理功能 內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!

推薦閱讀: