/**
* Copyright 2009-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.ibatis.executor.parameter;
import java.sql.PreparedStatement;
import java.sql.SQLException;
/**
* A parameter handler sets the parameters of the {@code PreparedStatement}.
* 參數(shù)處理器,設(shè)置參數(shù)到 {@code PreparedStatement}.
* @author Clinton Begin
*/
public interface ParameterHandler {
/**
* 獲取參數(shù)對象
* @return
*/
Object getParameterObject();
/**
* 設(shè)置參數(shù)對象到 {@code ps}
*/
void setParameters(PreparedStatement ps)
throws SQLException;
}
DefaultParameterHandler
/**
* Copyright 2009-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
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;
/**
* 默認的參數(shù)處理器
* @author Clinton Begin
* @author Eduardo Macarron
*/
public class DefaultParameterHandler implements ParameterHandler {
/**
* 類型處理接收器
*/
private final TypeHandlerRegistry typeHandlerRegistry;
/**
* Mapper.xml文件的select,delete,update,insert這些DML標簽的封裝類
*/
private final MappedStatement mappedStatement;
/**
* 參數(shù)對象
*/
private final Object parameterObject;
/**
* 可執(zhí)行SQL封裝
*/
private final BoundSql boundSql;
/**
* mybatis全局配置信息
*/
private final Configuration configuration;
/**
*
* @param mappedStatement Mapper.xml文件的select,delete,update,insert這些DML標簽的封裝類
* @param parameterObject 參數(shù)對象
* @param boundSql 可執(zhí)行SQL封裝
*/
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;
}
/**
* 獲取參數(shù)對象
*/
@Override
public Object getParameterObject() {
return parameterObject;
}
/**
* 設(shè)置參數(shù)對象到 {@code ps}
* @param ps 預編譯得SQL語句的對象,也就是說SQL語句被預編譯并存儲在PreparedStatement對象中,然后可以使用此對象多次高效地執(zhí)行改語句。
*/
@Override
public void setParameters(PreparedStatement ps) {
//設(shè)置錯誤日志上下文
ErrorContext.instance().activity("setting parameters").object(mappedStatement.getParameterMap().getId());
//獲取參數(shù)映射列表
List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();
//如果參數(shù)映射列表不為null
if (parameterMappings != null) {
//變量參數(shù)映射
for (int i = 0; i < parameterMappings.size(); i++) {
//獲取參數(shù)映射
ParameterMapping parameterMapping = parameterMappings.get(i);
//如果參數(shù)映射配置的模式不是輸出模式
if (parameterMapping.getMode() != ParameterMode.OUT) {
//新建一個參數(shù)對象
Object value;
//獲取參數(shù)映射配置的屬性
String propertyName = parameterMapping.getProperty();
//在boundSql中存在額外的參數(shù)
if (boundSql.hasAdditionalParameter(propertyName)) { // issue #448 ask first for additional params
//獲取額外參數(shù)
value = boundSql.getAdditionalParameter(propertyName);
//參數(shù)對象為null
} else if (parameterObject == null) {
value = null;
//存在類型接收處理器
} else if (typeHandlerRegistry.hasTypeHandler(parameterObject.getClass())) {
value = parameterObject;
} else {
//從元對象中獲取
MetaObject metaObject = configuration.newMetaObject(parameterObject);
value = metaObject.getValue(propertyName);
}
//獲取參數(shù)映射配置的TypeHandler
TypeHandler typeHandler = parameterMapping.getTypeHandler();
//獲取參數(shù)映射配置的jdbc類型
JdbcType jdbcType = parameterMapping.getJdbcType();
//如果值為null 且 jdbcType也為null
if (value == null && jdbcType == null) {
//獲取null對應的jdbcType
jdbcType = configuration.getJdbcTypeForNull();
}
try {
//將參數(shù)對應交給typeHandler賦值進ps
typeHandler.setParameter(ps, i + 1, value, jdbcType);
} catch (TypeException | SQLException e) {
throw new TypeException("Could not set parameters for mapping: " + parameterMapping + ". Cause: " + e, e);
}
}
}
}
}
}