ParameterHandler顾名思义是mybatis中的参数处理器,负责为 PreparedStatement 的 sql 语句参数动态赋值,这个接口很简单只有两个方法:
public interface ParameterHandler {
//读取参数
Object getParameterObject();
//用于对PreparedStatement的参数赋值.
void setParameters(PreparedStatement var1) throws SQLException;
}
PreparedStatement的继承体系
只有一个实现类DefaultParameterHandler
imageParameterHandler对象创建
参数处理器对象是在创建StatementHandler对象同时被创建的.由Configuration对象负责创建.
image创建时 传入三个对象:执行SQL对应的配置信息
- MappedStatement
- 参数对象Object
- SQL的BoundSql
一个BoundSql对象,代表了一次sql语句的实际执行,而SqlSource对象的责任,就是根据传入的参数对象,动态计算出这个BoundSql,也就是说Mapper文件中的节点的计算,是由SqlSource对象完成的。SqlSource最常用的实现类是DynamicSqlSource
ParameterHandler参数的由来
@Test
public void Test01(){
DeptDao dao = session.getMapper(DeptDao.class);
Dept dept = dao.findByDeptNo(10);
System.out.println(dept.getDname());
}
上述命令的实参10是如何添加到对应的SQL语句中的.
<select id="findByDeptNo" resultType="dept">
<include refid="DeptFindSql"></include>
where deptno = #{deptNo}
</select>
在mybatis中,使用动态代理模式.当dao.findByDeptNo(10)将要执行时;会被JVM进行拦截
交给mybatis中的代理实现类MapperProxy的invoke方法中
然后在一步步交给ParameterHandler中setParameter方法,将参数交给对应占位符
PrepareStatment的参数赋值
public void setParameters(PreparedStatement ps) {
ErrorContext.instance().activity("setting parameters").object(mappedStatement.getParameterMap().getId());
// parameterMappings是对#{}里给出的参数的封装,sql是一个参数话sql(sql中有占位符)
List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();
// 参数化sql需要设置参数,遍历这个参数列表,把参数设置到PreparedStatement中
if (parameterMappings != null) {
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)) {
// 获取对应的实参值
value = boundSql.getAdditionalParameter(propertyName);
} else if (parameterObject == null) {
value = null;
} else if (typeHandlerRegistry.hasTypeHandler(parameterObject.getClass())) {
value = parameterObject;// 实参可以直接通过TypeHandler转换为JdbcType
} else {
// 获取对象中相应的属性或查找Map对象中的值
MetaObject metaObject = configuration.newMetaObject(parameterObject);
value = metaObject.getValue(propertyName);
}
// 从parameterMapping中获取typeHandler对象
TypeHandler typeHandler = parameterMapping.getTypeHandler();
//从从parameterMapping获取参数对应的jdbcType
JdbcType jdbcType = parameterMapping.getJdbcType();
if (value == null && jdbcType == null) {
jdbcType = configuration.getJdbcTypeForNull();
}
try {
// 通过TypeHandler.setParameter方法会调用PreparedStaement.set*()方法
// 为SQL语句绑定相应实参
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);
}
}
}
}
}
原文地址
网友评论