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进行映射处理。