MyBatis SqlSession ParameterHandler执行实现原理概述

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/lichunericli/article/details/82563639

StatementHandler的执行步骤:https://blog.csdn.net/lichunericli/article/details/82563628

在StatementHandler的初始化时,会利用ParameterHandler来实现SQL语句的参数初始化,以完成预编译  
private Statement prepareStatement(StatementHandler handler, Log statementLog) throws SQLException {
  Connection connection = getConnection(statementLog);  // 通过Transaction获取数据库连接
  // 调用StatementHandler里的prepare方法预编译SQL语句并设置相关Statement参数
  Statement stmt = handler.prepare(connection, transaction.getTimeout());
  // SQL参数的设置,通过ParameterHandler来实现
  handler.parameterize(stmt);
  return stmt;
}  

1. ParameterHandler参数处理器的生成

public ParameterHandler newParameterHandler(mappedStatement, Object parameterObject, BoundSql boundSql) {
   ParameterHandler parameterHandler = mappedStatement.getLang().createParameterHandler(mappedStatement,
parameterObject, boundSql);  //  需要结合XMLLanguageDriver来生成参数处理器
   parameterHandler = (ParameterHandler) interceptorChain.pluginAll(parameterHandler);   //  注意拦截器对底层的影响
   return parameterHandler;
}  

2. SQL参数的初始化,在DefaultParameterHandler中实现

public void setParameters(PreparedStatement ps) {
  ErrorContext.instance().activity("setting parameters").object(mappedStatement.getParameterMap().getId());
  List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();
  if (parameterMappings != null) {  // 获取所有参数,注意ParameterMapping是java类型和jdbc类型的对应关系
    for (int i = 0; i < parameterMappings.size(); i++) {
      ParameterMapping parameterMapping = parameterMappings.get(i);
      if (parameterMapping.getMode() != ParameterMode.OUT) {   //  IN, OUT, INOUT
        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 {
            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 {  // 对应关系和值的处理对应
            typeHandler.setParameter(ps, i + 1, value, jdbcType);
        } catch (TypeException e) {
          throw new TypeException("Could not set parameters for mapping:");
        } catch (SQLException e) {
          throw new TypeException("Could not set parameters for mapping:");
        }
      }
    }
  }
}

总结:ParameterHandler的实现类只有DefaultParameterHandler,且提供的实现方法就两个:用getParameterObject()方法来获取参数,setParameters(PreparedStatement)方法来进行参数的设置。首先读取ParameterObject参数对象,然后用TypeHandler来对参数进行设置,而TypeHandler则需要对JdbcType和JavaType进行映射处理。

猜你喜欢

转载自blog.csdn.net/lichunericli/article/details/82563639