ParameterHandler 是MyBatis四大核心對(duì)象之一凯旭,ParameterHandler 相比于其他的組件就簡(jiǎn)單很多了十酣,ParameterHandler 譯為參數(shù)處理器存皂,負(fù)責(zé)為 PreparedStatement 的 sql 語(yǔ)句參數(shù)動(dòng)態(tài)賦值宾符,這個(gè)接口很簡(jiǎn)單只有兩個(gè)方法:
public interface ParameterHandler {
// 用于讀取參數(shù)踢星;
Object getParameterObject();
// 用于對(duì) PreparedStatement 綁定實(shí)參统刮。
void setParameters(PreparedStatement ps)
throws SQLException;
}
MyBatis為ParameterHandler 只提供了一個(gè)實(shí)現(xiàn)類故源,也就是后面要詳細(xì)介紹的DefaultParameterHandler遭贸。
下面先介紹下ParameterHandler 的創(chuàng)建過(guò)程和相關(guān)執(zhí)行流程:
1.ParameterHandler 的創(chuàng)建過(guò)程
2.ParameterHandler 的執(zhí)行過(guò)程
下面首先用流程圖表示一下 ParameterHandler 的執(zhí)行過(guò)程,以SimpleExecutor為例3.DefaultParameterHandler
DefaultParameterHandler的核心字段含義如下DefaultParameterHandler的核心方法是setParameters()方法心软,改方法主要負(fù)責(zé)調(diào)用PreparedStatment的set*()方法為SQL語(yǔ)句綁定實(shí)參:
public void setParameters(PreparedStatement ps) {
ErrorContext.instance().activity("setting parameters").object(mappedStatement.getParameterMap().getId());
// 從boundSql中獲取sql語(yǔ)句的參數(shù)映射列表壕吹, parameterMappings 就是對(duì) #{} 或者 ${} 里面參數(shù)的封裝
List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();
// 遍歷這個(gè)參數(shù)列表,把參數(shù)設(shè)置到PreparedStatement中
if (parameterMappings != null) {
for (int i = 0; i < parameterMappings.size(); i++) {
ParameterMapping parameterMapping = parameterMappings.get(i);
// 對(duì)于存儲(chǔ)過(guò)程中的參數(shù)不處理
if (parameterMapping.getMode() != ParameterMode.OUT) {
Object value;//綁定的實(shí)參
String propertyName = parameterMapping.getProperty();//參數(shù)的名字
if (boundSql.hasAdditionalParameter(propertyName)) {
// 獲取對(duì)應(yīng)的實(shí)參值
value = boundSql.getAdditionalParameter(propertyName);
} else if (parameterObject == null) {
value = null;
} else if (typeHandlerRegistry.hasTypeHandler(parameterObject.getClass())) {
value = parameterObject;// 實(shí)參可以直接通過(guò)TypeHandler轉(zhuǎn)換為JdbcType
} else {
// 獲取對(duì)象中相應(yīng)的屬性或查找Map對(duì)象中的值
MetaObject metaObject = configuration.newMetaObject(parameterObject);
value = metaObject.getValue(propertyName);
}
// 從parameterMapping中獲取typeHandler對(duì)象
TypeHandler typeHandler = parameterMapping.getTypeHandler();
//從從parameterMapping獲取參數(shù)對(duì)應(yīng)的jdbcType
JdbcType jdbcType = parameterMapping.getJdbcType();
if (value == null && jdbcType == null) {
jdbcType = configuration.getJdbcTypeForNull();
}
try {
// 通過(guò)TypeHandler.setParameter方法會(huì)調(diào)用PreparedStaement.set*()方法
// 為SQL語(yǔ)句綁定相應(yīng)實(shí)參
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);
}
}
}
}
}