在一段代码中,需要根据不同的条件多次调用一个存储过程,后来发现后面的调用,尽管传入的参数改变了,返回的值依然没有变。
下面的代码在同一个代码块中被调用了两次,代码如下:
Map<String,Object> rm2 = new HashMap<String, Object>();
rm2.put("sectionId", map.get("sectionId"));
rm2.put("longitude", start.get("lng"));
rm2.put("latitude", start.get("lat"));
String savePile2 = sectionService.savePile2(rm2);
mm.putAll(map2);
//mm.put("startPile", savePile2);
rm2.put("longitude", end.get("lng"));
rm2.put("latitude", end.get("lat"));
String savePile3 = sectionService.savePile2(rm2);
代码作用为,根据经纬度获取某一天的起始&结束位置,由于要获取某一区间的起始&结束位置,当传入日期为区间起始日期时,根据起始日期获取到的这一天的起始&结束经纬度,上面的代码调用一次,获取这一天的起始&结束位置,比较后,取两者之间的较小值,作为起始日期的开始位置。然后在传入区间的终止日期,根据终止日期获取这一天的起始&结束经纬度,上面的代码再调用一次,获取这一天的起始&结束位置,比较后,取两者之间的较大值,作为终止日期的结束位置。
特殊情况下,区间太小,起始日期和终止日期为同一天,那么相当于把相同的代码执行了两次,结果第二次执行时,出问题了。第一次执行时,savePile2=k2,savePile3=k3,当第二次再调用上面的代码时,相同的参数,savePile2却反悔k3,并不是k2。怀疑是Mybatis的缓存影响的,跟踪源码如下:
(1)调用开始
org.apache.ibatis.binding.MapperProxy.invoke(Object, Method, Object[])
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
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); //----> 调用
}
(2)
org.apache.ibatis.binding.MapperMethod.execute(SqlSession, Object[])
public Object execute(SqlSession sqlSession, Object[] args) {
Object result;
if (SqlCommandType.INSERT == command.getType()) {
Object param = method.convertArgsToSqlCommandParam(args);
result = rowCountResult(sqlSession.insert(command.getName(), param));
} else if (SqlCommandType.UPDATE == command.getType()) {
Object param = method.convertArgsToSqlCommandParam(args);
result = rowCountResult(sqlSession.update(command.getName(), param));
} else if (SqlCommandType.DELETE == command.getType()) {
Object param = method.convertArgsToSqlCommandParam(args);
result = rowCountResult(sqlSession.delete(command.getName(), param));
} else if (SqlCommandType.SELECT == command.getType()) {
if (method.returnsVoid() && method.hasResultHandler()) {
executeWithResultHandler(sqlSession, args);
result = null;
} else if (method.returnsMany()) {
result = executeForMany(sqlSession, args);
} else if (method.returnsMap()) {
result = executeForMap(sqlSession, args);
} else {//存储过程,会执行到这里
Object param = method.convertArgsToSqlCommandParam(args);
result = sqlSession.selectOne(command.getName(), param); //---> 调用
}
} else if (SqlCommandType.FLUSH == command.getType()) {
result = sqlSession.flushStatements();
} else {
throw new BindingException("Unknown execution method for: " + command.getName());
}
if (result == null && method.getReturnType().isPrimitive() && !method.returnsVoid()) {
throw new Binding