ParameterHandler

作者: 93张先生 | 来源:发表于2020-08-30 22:46 被阅读0次

    ParameterHandler

    ParameterHandler 是一个 SQL 实参处理器,主要功能是为 SQL 语句 绑定实参,使用传入的实参替换 SQL 吾句的中 ? 占位符。

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

    DefaultParameterHandler

    DefaultParameterHandler 是 ParameterHandler 接口唯一默认实现类。

    在 BoundSql 中记录的 SQL 语句中可能包含"?"占位符,而每个"?"占位符都对应了 BoundSql.parameterMappings 集合中的一个元素,在该 ParameterMapping 中记录了对应的参数名称以及该参数的相关属性。

    public class DefaultParameterHandler implements ParameterHandler {
      // TypeHandlerRegistry 对象,管理 MyBatis 中的 全部 TypeHandler 对象
      private final TypeHandlerRegistry typeHandlerRegistry;
      // MappedSt tement 对象,其中记录 SQL 节点相应的配置信息
      private final MappedStatement mappedStatement;
      // 用户传入的实参对象
      private final Object parameterObject;
      // 包含 "?" 占位符的,包含数据库将要执行的 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;
      }
    
      /**
       * 将 BoundSql 中,含有 "?" 占位符替换为实参。
       * setParameters 会遍历 BoundSql.parameterMappings 集合中记录的 ParameterMapping 对象,井根据其中记录的参数名称查找相应实参 然后与 SQL 语句绑定。
       * @param ps
       */
      @Override
      public void setParameters(PreparedStatement ps) {
        ErrorContext.instance().activity("setting parameters").object(mappedStatement.getParameterMap().getId());
        // 取出 sql 中的参数映射列表
        List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();
        if (parameterMappings != null) {
          for (int i = 0; i < parameterMappings.size(); i++) {
            ParameterMapping parameterMapping = parameterMappings.get(i);
            // 过滤掉存储过程中的输出参数
            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 转换成 JdbcType
                value = parameterObject;
              } else {
                // 获取对象中相应的属性位或查找 Map 对象中位
                MetaObject metaObject = configuration.newMetaObject(parameterObject);
                value = metaObject.getValue(propertyName);
              }
              // 获取 ParameterMapping 中设置的 TypeHandler 对象
              TypeHandler typeHandler = parameterMapping.getTypeHandler();
              JdbcType jdbcType = parameterMapping.getJdbcType();
              if (value == null && jdbcType == null) {
                jdbcType = configuration.getJdbcTypeForNull();
              }
              try {
                // 通过 TypeHandler setParameter() 方法会调用 PreparedStatement.set *() 方法,为 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);
              }
            }
          }
        }
      }
    
    }
    

    相关文章

      网友评论

        本文标题:ParameterHandler

        本文链接:https://www.haomeiwen.com/subject/hbkysktx.html