一、创建代理对象会进入一个MapperProxy的类
EMPDAO ed = sqlSession.getMapper(EMPDAO.class);
ed//代理对象
MapperProxy类中invoke方法
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//如果传进来的参数是obj类型 直接放行
if (Object.class.equals(method.getDeclaringClass())) {
try {
return method.invoke(this, args);
} catch (Throwable t) {
throw ExceptionUtil.unwrapThrowable(t);
}
}
final MapperMethod mapperMethod = cachedMapperMethod(method);
return mapperMethod.execute(sqlSession, args);
}
public Object convertArgsToSqlCommandParam(Object[] args) {
//params是一个Map key是0、1、2... value是用Param新起的名字
final int paramCount = params.size();
//如果传进来的参数是null 并且paramCount == 0
if (args == null || paramCount == 0) {
return null;
} else if (!hasNamedParameters && paramCount == 1) {
return args[params.keySet().iterator().next().intValue()];
} else {
final Map<String, Object> param = new ParamMap<Object>();
int i = 0;
for (Map.Entry<Integer, String> entry : params.entrySet()) {
param.put(entry.getValue(), args[entry.getKey().intValue()]);
// issue #71, add param names as param1, param2...but ensure backward compatibility
final String genericParamName = "param" + String.valueOf(i + 1);
if (!param.containsKey(genericParamName)) {
param.put(genericParamName, args[entry.getKey()]);
}
i++;
}
return param;
}
}
一、mybatis取值指定参数
规定参数的一下规则:javaType、 jdbcType、 mode(存储过程)、 numericScale、
resultMap、 typeHandler、 jdbcTypeName、 expression(未来准备支持的功能)
二、Mybatis中null类型处理
JdbcType OTHER
在Mybatis中 所有null类型映射的都是jdbc中other类型
public enum JdbcType {
/*
* This is added to enable basic support for the
* ARRAY data type - but a custom type handler is still required
*/
ARRAY(Types.ARRAY),
BIT(Types.BIT),
TINYINT(Types.TINYINT),
SMALLINT(Types.SMALLINT),
INTEGER(Types.INTEGER),
BIGINT(Types.BIGINT),
FLOAT(Types.FLOAT),
REAL(Types.REAL),
DOUBLE(Types.DOUBLE),
NUMERIC(Types.NUMERIC),
DECIMAL(Types.DECIMAL),
CHAR(Types.CHAR),
VARCHAR(Types.VARCHAR),
LONGVARCHAR(Types.LONGVARCHAR),
DATE(Types.DATE),
TIME(Types.TIME),
TIMESTAMP(Types.TIMESTAMP),
BINARY(Types.BINARY),
VARBINARY(Types.VARBINARY),
LONGVARBINARY(Types.LONGVARBINARY),
NULL(Types.NULL),
OTHER(Types.OTHER), // 在Mybatis中null类型映射的是Jdbc中的OTHER类型
BLOB(Types.BLOB),
CLOB(Types.CLOB),
BOOLEAN(Types.BOOLEAN),
CURSOR(-10), // Oracle
UNDEFINED(Integer.MIN_VALUE + 1000),
NVARCHAR(Types.NVARCHAR), // JDK6
NCHAR(Types.NCHAR), // JDK6
NCLOB(Types.NCLOB), // JDK6
STRUCT(Types.STRUCT),
JAVA_OBJECT(Types.JAVA_OBJECT),
DISTINCT(Types.DISTINCT),
REF(Types.REF),
DATALINK(Types.DATALINK),
ROWID(Types.ROWID), // JDK6
LONGNVARCHAR(Types.LONGNVARCHAR), // JDK6
SQLXML(Types.SQLXML), // JDK6
DATETIMEOFFSET(-155); // SQL Server 2008
解决办法
1、在mapper文件中的sql语句中加入jdbcType = NULL
#{hireDate,jdbcType = NULL} //2、在全局配置
<setting name="jdbcTypeForNull" value="NULL|VARCHAR|OTHER">
本文探讨了MyBatis框架中代理对象的创建过程及其内部实现原理,特别是在MapperProxy类中的invoke方法如何处理方法调用。同时,深入解析了参数转换逻辑及MyBatis如何处理null类型的值。
8013

被折叠的 条评论
为什么被折叠?



