在StatementHandler使用prepare()方法后,接下来就是使用ParameterHandler来设置参数,让我们看看它的定义:

package org.apache.ibatis.executor.parameter;  

import java.sql.PreparedStatement;
import java.sql.SQLException; /**
* A parameter handler sets the parameters of the {@code PreparedStatement}
*
* @author Clinton Begin
*/
public interface ParameterHandler { Object getParameterObject(); void setParameters(PreparedStatement ps)
throws SQLException; }

getParameterObject()是获取参数的,而setParameters()是设置参数的,相当于对一条sql所有的参数都执行ps.setXXX(value);

DefaultParameterHandler是它的实现类:

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; /**
* @author Clinton Begin
* @author Eduardo Macarron
*/
public class DefaultParameterHandler implements ParameterHandler { private final TypeHandlerRegistry typeHandlerRegistry; private final MappedStatement mappedStatement;
private final Object parameterObject; //所有的参数值
private BoundSql boundSql;
private Configuration configuration; 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;
} @Override
public Object getParameterObject() {
return parameterObject;
} @Override
public void setParameters(PreparedStatement ps) {
ErrorContext.instance().activity("setting parameters").object(mappedStatement.getParameterMap().getId());
//获取所有参数,ParameterMapping是java类型和jdbc类型的对应关系
List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();
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)) { // 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);
}
//获取参数值对应的jdbc类型
TypeHandler typeHandler = parameterMapping.getTypeHandler();
JdbcType jdbcType = parameterMapping.getJdbcType();
if (value == null && jdbcType == null) {
jdbcType = configuration.getJdbcTypeForNull();
}
try {
//设置参数值和jdbc类型的对应关系
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);
}
}
}
}
} }

getParameterObject是获取参数,这个参数值就是你传递进来的值,可能是个实体、map或单个基本类型数据。

重点看setParameters(),首先它读取了ParameterObject参数对象,然后用typeHandler对参数进行设置,而typeHandler里面需要对jdbcType和javaType进行处理,然后就设置参数了。也很好理解。所以当我们使用TypeHandler的时候完全可以控制如何设置SQL参数。设置参数,其实就是你在sql语句中配置的java对象和jdbc类型对应的关系,例如#{id,jdbcType=INTEGER},id默认类型是javaType=class java.lang.Integer。

  

MyBatis框架的使用及源码分析(十二) ParameterHandler的更多相关文章

  1. MyBatis框架的使用及源码分析(十) CacheExecutor,SimpleExecutor,BatchExecutor ,ReuseExecutor

    Executor分成两大类,一类是CacheExecutor,另一类是普通Executor. 普通类又分为: ExecutorType.SIMPLE: 这个执行器类型不做特殊的事情.它为每个语句的执行 ...

  2. MyBatis框架的使用及源码分析(十一) StatementHandler

    我们回忆一下<MyBatis框架的使用及源码分析(十) CacheExecutor,SimpleExecutor,BatchExecutor ,ReuseExecutor> , 这4个Ex ...

  3. MyBatis框架的使用及源码分析(九) Executor

    从<MyBatis框架的使用及源码分析(八) MapperMethod>文中我们知道执行Mapper的每一个接口方法,最后调用的是MapperMethod.execute方法.而当执行Ma ...

  4. ABP源码分析十二:本地化

    本文逐个分析ABP中涉及到locaization的接口和类,以及相互之间的关系.本地化主要涉及两个方面:一个是语言(Language)的管理,这部分相对简单.另一个是语言对应得本地化资源(Locali ...

  5. [Abp 源码分析]十二、多租户体系与权限验证

    0.简介 承接上篇文章我们会在这篇文章详细解说一下 Abp 是如何结合 IPermissionChecker 与 IFeatureChecker 来实现一个完整的多租户系统的权限校验的. 1.多租户的 ...

  6. jQuery 源码分析(十二) 数据操作模块 html特性 详解

    jQuery的属性操作模块总共有4个部分,本篇说一下第1个部分:HTML特性部分,html特性部分是对原生方法getAttribute()和setAttribute()的封装,用于修改DOM元素的特性 ...

  7. Vue.js 源码分析(十二) 基础篇 组件详解

    组件是可复用的Vue实例,一个组件本质上是一个拥有预定义选项的一个Vue实例,组件和组件之间通过一些属性进行联系. 组件有两种注册方式,分别是全局注册和局部注册,前者通过Vue.component() ...

  8. MyBatis框架的使用及源码分析(八) MapperMethod

    从 <MyBatis框架中Mapper映射配置的使用及原理解析(七) MapperProxy,MapperProxyFactory> 文中,我们知道Mapper,通过MapperProxy ...

  9. MyBatis框架的使用及源码分析(六) MapperRegistry

    我们先Mapper接口的调用方式,见<MyBatis框架中Mapper映射配置的使用及原理解析(一) 配置与使用>的示例: public void findUserById() { Sql ...

随机推荐

  1. 【转】Charles 从入门到精通

    目录与版权 转载请保留顶部的 Charles 中国特惠内容,本文的内容主要包括: Charles 的简介 如何安装 Charles 将 Charles 设置成系统代理 Charles 主界面介绍 过滤 ...

  2. VBA基础之Excel VBA 表格的操作(一)

    一.Excel VBA 表格的操作1. Excel表格的指定以及表格属性的设置 Sub main() '把表格B2的值改为"VBA Range和Cells函数" Range(&qu ...

  3. 用纯css改变下拉列表select框的默认样式(转)

    用纯css改变下拉列表select框的默认样式 分享到 分类 JS学习   关键字 前端   发布 kris  2015-04-01 注意 转载须保留原文链接,译文链接,作者译者等信息.     在这 ...

  4. Android 数据存储 之 SQLite数据库详解

    . 作者 :万境绝尘 转载请注明出处 : http://blog.csdn.net/shulianghan/article/details/19028665 . SQLiteDataBase示例程序下 ...

  5. ubuntu apache nginx 启动 关闭

    转载自:http://www.comflag.com/2011/05/01/apache-web.htm 电影<社交网络>中,facebook创始人马克.扎克失恋后入侵哈佛大学宿舍楼服务器 ...

  6. TCP 的有限状态机

    TCP 有限状态机的图中每一个方框都是 TCP 可能具有的状态. 每个方框中的大写英文字符串是 TCP 标准所使用的 TCP 连接状态名. 状态之间的箭头表示可能发生的状态变迁. 箭头旁边的字,表明引 ...

  7. shell练习题讲解

    写一个脚本,计算100以内所有的奇数的和以及所有偶数的和,分别显示出来#! /bin/bashsum1=0for i in `seq 1 2 100`do sum1=$[$sum1+$i]doneec ...

  8. C#中的反射和扩展方法的运用

    前段时间做了一个练手的小项目,采用的是三层架构,也就是Models,IDAL,DAL,BLL 和 Web , 在DAL层中各个类中有一个方法比较常用,那就是 RowToClass ,顾名思义,也就是将 ...

  9. java直接访问JNDI工具代码

    import java.sql.*; import java.util.*; import javax.naming.*; import javax.sql.DataSource; public cl ...

  10. matlab中nargin函数的用法

    nargin是用来判断输入变量个数的函数,这样就可以针对不同的情况执行不同的功能. 通常可以用他来设定一些默认值,如下面的函数. 例子,函数test1的功能是输出a和b的和.如果只输入一个变量,则认为 ...