zoukankan      html  css  js  c++  java
  • MyBatis框架的使用及源码分析(十二) ParameterHandler

    在StatementHandler使用prepare()方法后,接下来就是使用ParameterHandler来设置参数,让我们看看它的定义: 

    package org.apache.ibatis.executor.parameter;  
      
    import java.sql.PreparedStatement;  
    import java.sql.SQLException;  
      
    /** 
     * A parameter handler sets the parameters of the {@code PreparedStatement} 
     * 
     * @author Clinton Begin 
     */  
    public interface ParameterHandler {  
      
      Object getParameterObject();  
      
      void setParameters(PreparedStatement ps)  
          throws SQLException;  
      
    }  
    

    getParameterObject()是获取参数的,而setParameters()是设置参数的,相当于对一条sql所有的参数都执行ps.setXXX(value);

      

    DefaultParameterHandler是它的实现类:

    package org.apache.ibatis.scripting.defaults;  
      
    import java.sql.PreparedStatement;  
    import java.sql.SQLException;  
    import java.util.List;  
      
    import org.apache.ibatis.executor.ErrorContext;  
    import org.apache.ibatis.executor.parameter.ParameterHandler;  
    import org.apache.ibatis.mapping.BoundSql;  
    import org.apache.ibatis.mapping.MappedStatement;  
    import org.apache.ibatis.mapping.ParameterMapping;  
    import org.apache.ibatis.mapping.ParameterMode;  
    import org.apache.ibatis.reflection.MetaObject;  
    import org.apache.ibatis.session.Configuration;  
    import org.apache.ibatis.type.JdbcType;  
    import org.apache.ibatis.type.TypeException;  
    import org.apache.ibatis.type.TypeHandler;  
    import org.apache.ibatis.type.TypeHandlerRegistry;  
      
    /** 
     * @author Clinton Begin 
     * @author Eduardo Macarron 
     */  
    public class DefaultParameterHandler implements ParameterHandler {  
      
      private final TypeHandlerRegistry typeHandlerRegistry;  
      
      private final MappedStatement mappedStatement;  
      private final Object parameterObject;  //所有的参数值  
      private BoundSql boundSql;  
      private 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;  
      }  
      
      @Override  
      public void setParameters(PreparedStatement ps) {  
        ErrorContext.instance().activity("setting parameters").object(mappedStatement.getParameterMap().getId());  
        //获取所有参数,ParameterMapping是java类型和jdbc类型的对应关系  
        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()))  
                //如果是单个值则直接赋值     
                value = parameterObject;  
              } else {  
                MetaObject metaObject = configuration.newMetaObject(parameterObject);  
                value = metaObject.getValue(propertyName);  
              }  
              //获取参数值对应的jdbc类型  
              TypeHandler typeHandler = parameterMapping.getTypeHandler();  
              JdbcType jdbcType = parameterMapping.getJdbcType();  
              if (value == null && jdbcType == null) {  
                jdbcType = configuration.getJdbcTypeForNull();  
              }  
              try {  
                //设置参数值和jdbc类型的对应关系  
                typeHandler.setParameter(ps, i + 1, value, jdbcType);  
              } catch (TypeException e) {  
                throw new TypeException("Could not set parameters for mapping: " + parameterMapping + ". Cause: " + e, e);  
              } catch (SQLException e) {  
                throw new TypeException("Could not set parameters for mapping: " + parameterMapping + ". Cause: " + e, e);  
              }  
            }  
          }  
        }  
      }  
      
    }  
    

    getParameterObject是获取参数,这个参数值就是你传递进来的值,可能是个实体、map或单个基本类型数据。

    重点看setParameters(),首先它读取了ParameterObject参数对象,然后用typeHandler对参数进行设置,而typeHandler里面需要对jdbcType和javaType进行处理,然后就设置参数了。也很好理解。所以当我们使用TypeHandler的时候完全可以控制如何设置SQL参数。设置参数,其实就是你在sql语句中配置的java对象和jdbc类型对应的关系,例如#{id,jdbcType=INTEGER},id默认类型是javaType=class java.lang.Integer。

      

  • 相关阅读:
    Java.io.outputstream.PrintStream:打印流
    Codeforces 732F. Tourist Reform (Tarjan缩点)
    退役了
    POJ 3281 Dining (最大流)
    Light oj 1233
    Light oj 1125
    HDU 5521 Meeting (最短路)
    Light oj 1095
    Light oj 1044
    HDU 3549 Flow Problem (dinic模版 && isap模版)
  • 原文地址:https://www.cnblogs.com/zsg88/p/7571960.html
Copyright © 2011-2022 走看看