preparestatment获取sql_mybatis四大神器之ParameterHandler

ParameterHandler顾名思义是mybatis中的参数处理器,负责为 PreparedStatement 的 sql 语句参数动态赋值,这个接口很简单只有两个方法:

public interface ParameterHandler {

//读取参数

Object getParameterObject();

//用于对PreparedStatement的参数赋值.

void setParameters(PreparedStatement var1) throws SQLException;

}

PreparedStatement的继承体系

只有一个实现类DefaultParameterHandler

image

ParameterHandler对象创建

参数处理器对象是在创建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语句中的.

where deptno = #{deptNo}

在mybatis中,使用动态代理模式.当dao.findByDeptNo(10)将要执行时;会被JVM进行拦截

交给mybatis中的代理实现类MapperProxy的invoke方法中

image

然后在一步步交给ParameterHandler中setParameter方法,将参数交给对应占位符

PrepareStatment的参数赋值

public void setParameters(PreparedStatement ps) {

ErrorContext.instance().activity("setting parameters").object(mappedStatement.getParameterMap().getId());

// parameterMappings是对#{}里给出的参数的封装,sql是一个参数话sql(sql中有占位符)

List 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);

}

}

}

}

}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值