Mybatis源碼解析06-關鍵組件ParameterHandler

ParameterHandler顯然是用來處理參數的,主要是用來設置PreparedStatement的參數,接口只有兩個方法,一個是獲取參數對象,一個是設置PreparedStatement的參數。PreparementStatement會

public interface ParameterHandler {    
  Object getParameterObject();  
  void setParameters(PreparedStatement ps) throws SQLException;  
}

此接口只有一個實現類:DefaultParameterHandler。 可以看到在創建StatementHandler實例調用BaseStatementHandler的構造器時,會創建ParameterHandler

protected BaseStatementHandler(Executor executor, MappedStatement mappedStatement, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) {
	this.parameterHandler = configuration.newParameterHandler(mappedStatement, parameterObject, boundSql);
}

這裏我們重點看一下setParameters方法的實現:

public class DefaultParameterHandler implements ParameterHandler {
	@Override  
	public void setParameters(PreparedStatement ps) {  
	  ErrorContext.instance().activity("setting parameters").object(mappedStatement.getParameterMap().getId());  
	  // 會從BoundSql裏面拿到ParameterMappings對象
	  List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();  
	  if (parameterMappings != null) {  
	    for (int i = 0; i < parameterMappings.size(); i++) {  
	      ParameterMapping parameterMapping = parameterMappings.get(i);  
	      // 非存儲過程的OUT類型
	      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())) {  
	          // 如果有對應的typeHandler則,value就爲paremeterObject
	          value = parameterObject;  
	        } else {  
	          // 否則創建一個新的MetaObject
	          MetaObject metaObject = configuration.newMetaObject(parameterObject);  
	          value = metaObject.getValue(propertyName);  
	        }  
		    // 拿到TypeHandler和JdbcType
	        TypeHandler typeHandler = parameterMapping.getTypeHandler();  
	        JdbcType jdbcType = parameterMapping.getJdbcType();  
	        // 如果兩個都爲空,則設置jdbcType爲JdbcType.OTHER
	        if (value == null && jdbcType == null) {  
	          jdbcType = configuration.getJdbcTypeForNull();  
	        }  
	        try {  
		      // 調用typeHandler的setParameter來設置參數,最終會根據類型調用PreparementStatement的setXXX方法,來設置對應的值
	          typeHandler.setParameter(ps, i + 1, value, jdbcType);  
	        } catch (TypeException | SQLException e) {  
	          throw new TypeException("Could not set parameters for mapping: " + parameterMapping + ". Cause: " + e, e);  
	        }  
	      }  
	    }  
	  }  
	}
}

可以看到ParamenterHandler相對比較簡單,主要是根據配置解析的ParameterMapping(參數映射)找到對應的TypeHandler和JdbcType,最終會調用到PreparedStatement的設置參數方法。

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