首頁 > 軟體

java executor包引數處理功能 

2022-02-15 19:00:12

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包引數處理功能 內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com