主要是给声明里面填充参数
一、创建参数处理器
在声明处理器基类中:
this.parameterHandler = configuration.newParameterHandler(mappedStatement, parameterObject, boundSql);
对应configuration里面:
public ParameterHandler newParameterHandler(MappedStatement mappedStatement, Object parameterObject, BoundSql boundSql) {
ParameterHandler parameterHandler = mappedStatement.getLang().createParameterHandler(mappedStatement, parameterObject, boundSql);
parameterHandler = (ParameterHandler) interceptorChain.pluginAll(parameterHandler);
return parameterHandler;
}
parameterHandler = (ParameterHandler) interceptorChain.pluginAll(parameterHandler);
表明在参数处理之前可以定义拦截处理
二、调用参数处理器
跟踪进去发现createParameterHandler里面都是使用DefaultParameterHandler这个参数处理器。
在声明处理器中都有:
public void parameterize(Statement statement) throws SQLException {
parameterHandler.setParameters((PreparedStatement) statement);
}
在执行器中有:
private Statement prepareStatement(StatementHandler handler, Log statementLog) throws SQLException {
Statement stmt;
Connection connection = getConnection(statementLog);
stmt = handler.prepare(connection);
handler.parameterize(stmt);
return stmt;
}
到这里也就知道了,执行器调用声明处理器
parameterize方法,
parameterize方法调用参数处理器
parameterHandler填充参数
三、参数处理器如何填充参数
public void setParameters(PreparedStatement ps) throws SQLException {
ErrorContext.instance().activity("setting parameters").object(mappedStatement.getParameterMap().getId());
List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();
if (parameterMappings != null) {
MetaObject metaObject = parameterObject == null ? null : configuration.newMetaObject(parameterObject);
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 {
value = metaObject == null ? null : metaObject.getValue(propertyName);
}
TypeHandler typeHandler = parameterMapping.getTypeHandler();
JdbcType jdbcType = parameterMapping.getJdbcType();
if (value == null && jdbcType == null) jdbcType = configuration.getJdbcTypeForNull();
typeHandler.setParameter(ps, i + 1, value, jdbcType);
}
}
}
}
该部分是获取参数mapping,然后怎么获取字段的值,也就是说这里都是mybatis提供的解析,如何获取参数值,在拦截器中可以借鉴
TypeHandler 类型处理器含有org.apache.ibatis.type里面的基础类型处理器,还有自己注册的类型处理器
BaseTypeHandler类型处理器基类里面setParameter可以看到就是使用各个类型给声明填充参数。