深入了解深入了解MyBatis参数参数
今天小编就为大家分享一篇关于深入了解MyBatis参数,小编觉得内容挺不错的,现在分享给大家,具有很好的
参考价值,需要的朋友一起跟随小编来看看吧
深入了解深入了解MyBatis参数参数
相信很多人可能都遇到过下面这些异常:
"Parameter 'xxx' not found. Available parameters are [...]"
"Could not get property 'xxx' from xxxClass. Cause:
"The expression 'xxx' evaluated to a null value."
"Error evaluating expression 'xxx'. Return value (xxxxx) was not iterable."
不只是上面提到的这几个,我认为有很多的错误都产生在和参数有关的地方。
想要避免参数引起的错误,我们需要深入了解参数。
想了解参数,我们首先看MyBatis处理参数和使用参数的全部过程。
本篇由于为了便于理解和深入,使用了大量的源码,因此篇幅较长,需要一定的耐心看完,本文一定会对你起到很大的帮助。
参数处理过程参数处理过程
处理接口形式的入参处理接口形式的入参
在使用MyBatis时,有两种使用方法。一种是使用的接口形式,另一种是通过SqlSession调用命名空间。这两种方式在传递参
数时是不一样的,命名空间的方式更直接,但是多个参数时需要我们自己创建Map作为入参。相比而言,使用接口形式更简
单。
接口形式的参数是由MyBatis自己处理的。如果使用接口调用,入参需要经过额外的步骤处理入参,之后就和命名空间方式一
样了。
在MapperMethod.java会首先经过下面方法来转换参数:
public Object convertArgsToSqlCommandParam(Object[] args) {
final int paramCount = params.size();
if (args == null || paramCount == 0) {
return null;
} else if (!hasNamedParameters && paramCount == 1) {
return args[params.keySet().iterator().next()];
} 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()]);
// 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;
}
}
在这里有个很关键的params,这个参数类型为Map<Integer, String>,他会根据接口方法按顺序记录下接口参数的定义的名
字,如果使用@Param指定了名字,就会记录这个名字,如果没有记录,那么就会使用它的序号作为名字。
例如有如下接口:
List<User> select(@Param('sex')String sex,Integer age);
那么他对应的params如下:
{
0:'sex',
1:'1'
}
继续看上面的convertArgsToSqlCommandParam方法,这里简要说明3种情况:
入参为null或没有时,参数转换为null