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的设置参数方法。

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