parameterhandler 的核心任务是将 java 参数安全绑定到 preparedstatement 占位符,通过 typehandler 转换类型并调用 jdbc 方法设置值;它由 statementhandler 创建并持有,执行 setparameters 时遍历 parametermapping、提取值、委托 typehandler 处理 null 和自定义逻辑,并支持拦截器介入。

MyBatis 中 ParameterHandler 的核心任务,就是把 Java 方法传入的参数对象(比如 POJO、Map 或基本类型)准确、安全地绑定到 JDBC PreparedStatement 的问号占位符上。它不直接操作 SQL 字符串,而是依托类型系统和映射规则完成“值→JDBC类型→预编译语句”的转化。
ParameterHandler 的创建时机与持有关系
它由 StatementHandler(通常是 PreparedStatementHandler)在初始化时创建,并作为其成员变量持有。创建过程走的是 MyBatis 的工厂链:
- StatementHandler 构造时,从 Configuration 中调用
newParameterHandler() - 该方法返回一个被拦截器代理过的
DefaultParameterHandler实例 - 构造所需的关键信息包括:
MappedStatement(含 SQL 和映射定义)、parameterObject(用户传参)、boundSql(已解析动态 SQL 后的最终 SQL 与ParameterMapping列表)
setParameters() 方法执行参数绑定的核心流程
当 StatementHandler 执行 parameterize(statement) 时,实际委托给 ParameterHandler 的 setParameters(ps) 方法。该方法内部逻辑清晰:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 从
boundSql.getParameterMappings()获取所有ParameterMapping对象列表 - 遍历每个
ParameterMapping,它封装了:属性名(如user.name)、Java 类型、JDBC 类型、指定的TypeHandler等 - 调用
getParameterValue(parameterMapping)提取对应值:若参数是简单类型(String/Integer等),直接返回;若是复杂对象(如 User),则通过反射获取字段值 - 根据
ParameterMapping中指定或推断出的TypeHandler,调用其setParameter(ps, index, value, jdbcType) -
TypeHandler最终调用ps.setString(i+1, value)、ps.setInt(i+1, value)等原生 JDBC 方法完成设置
Null 值与自定义 TypeHandler 的处理
ParameterHandler 本身不判断 null,而是交由 TypeHandler 处理:
- 如果参数值为
null,且未显式配置jdbcType(如#{name,jdbcType=VARCHAR}),MyBatis 可能抛出异常或使用默认策略 - 若指定了
jdbcType,TypeHandler会调用ps.setNull(index, jdbcType) - 自定义
TypeHandler可在setParameter中加入加密、脱敏、格式转换等逻辑,只要它实现了正确类型转换即可被 ParameterHandler 无缝调用
拦截器对参数设置的介入点
你可以编写 @Intercepts(@Signature(..., method = "setParameters", ...)) 拦截器,在参数真正写入 PreparedStatement 前进行干预:
- 适用于统一参数校验、敏感字段自动加解密、日志审计等场景
- 注意:拦截的是
ParameterHandler.setParameters(),不是 StatementHandler 的方法 - 代理对象拿到的是原始
PreparedStatement,可读取已有参数或修改即将写入的值
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










