ParameterHandler接口是参数处理器,位于mybatis包的org.apache.ibatis.executor.parameter下,源码如下:
1 public interface ParameterHandler { 2 3 Object getParameterObject();//获取参数 4 5 void setParameters(PreparedStatement ps)//设置参数 6 throws SQLException; 7 8 }
可见ParameterHandler接口只有简单的两个方法,一个是获取参数一个是设置参数。ParameterHandler接口默认实现类是DefaultParameterHandler,主要源码如下:
1 public class DefaultParameterHandler implements ParameterHandler { 2 3 private final TypeHandlerRegistry typeHandlerRegistry; 4 5 private final MappedStatement mappedStatement; 6 private final Object parameterObject; 7 private BoundSql boundSql; 8 private Configuration configuration; 9 10 public DefaultParameterHandler(MappedStatement mappedStatement, Object parameterObject, BoundSql boundSql) { 11 this.mappedStatement = mappedStatement; 12 this.configuration = mappedStatement.getConfiguration(); 13 this.typeHandlerRegistry = mappedStatement.getConfiguration().getTypeHandlerRegistry(); 14 this.parameterObject = parameterObject;//设置参数 15 this.boundSql = boundSql; 16 } 17 18 @Override 19 public Object getParameterObject() { 20 return parameterObject;//返回参数 21 } 22 23 @Override 24 public void setParameters(PreparedStatement ps) { 25 ErrorContext.instance().activity("setting parameters").object(mappedStatement.getParameterMap().getId()); 26 List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();//获取所有参数,ParameterMapping是jdbc和java类型之间的对应关系 27 if (parameterMappings != null) { 28 //遍历所有参数,将java 类型设置成jdbc类型 29 for (int i = 0; i < parameterMappings.size(); i++) { 30 ParameterMapping parameterMapping = parameterMappings.get(i); 31 if (parameterMapping.getMode() != ParameterMode.OUT) { 32 Object value; 33 String propertyName = parameterMapping.getProperty(); 34 if (boundSql.hasAdditionalParameter(propertyName)) { // issue #448 ask first for additional params 35 value = boundSql.getAdditionalParameter(propertyName); 36 } else if (parameterObject == null) { 37 value = null; 38 } else if (typeHandlerRegistry.hasTypeHandler(parameterObject.getClass())) { 39 value = parameterObject; 40 } else { 41 MetaObject metaObject = configuration.newMetaObject(parameterObject); 42 value = metaObject.getValue(propertyName); 43 } 44 TypeHandler typeHandler = parameterMapping.getTypeHandler(); 45 JdbcType jdbcType = parameterMapping.getJdbcType(); 46 if (value == null && jdbcType == null) { 47 jdbcType = configuration.getJdbcTypeForNull(); 48 } 49 try { 50 typeHandler.setParameter(ps, i + 1, value, jdbcType); 51 } catch (TypeException e) { 52 throw new TypeException("Could not set parameters for mapping: " + parameterMapping + ". Cause: " + e, e); 53 } catch (SQLException e) { 54 throw new TypeException("Could not set parameters for mapping: " + parameterMapping + ". Cause: " + e, e); 55 } 56 } 57 } 58 } 59 } 60 61 }
而ParameterHandler的初始化同样也是在Configuration中实现的,代码如下:
1 public ParameterHandler newParameterHandler(MappedStatement mappedStatement, Object parameterObject, BoundSql boundSql) { 2 ParameterHandler parameterHandler = mappedStatement.getLang().createParameterHandler(mappedStatement, parameterObject, boundSql); 3 parameterHandler = (ParameterHandler) interceptorChain.pluginAll(parameterHandler); 4 return parameterHandler; 5 }