在Java中使用iBatis调用存储过程的核心是通过SqlMapClient的queryForObject或update方法,配置SqlMap.xml中的statement标签,指定parameterClass和resultClass。返回值获取技巧:对于输出参数,使用HashMap传递输入输出参数,存储过程执行后从Map中取出key对应的值。示例代码:
SqlMapClient sqlMapClient = ...;
HashMap params = new HashMap();
params.put("inParam", "inputValue");
Object result = sqlMapClient.queryForObject("callProc", params);
String outValue = (String) params.get("outParam");
这样就能高效获取存储过程的返回值。
配置SqlMap.xml调用存储过程
<procedure id="callMyProc" parameterClass="java.util.Map">
<![CDATA[call my_stored_procedure(?,?,?)]]>
</procedure>
输入参数顺序与存储过程一致,最后一个参数为输出。调用时Map中放入所有参数,iBatis自动映射。
处理多个输出参数
存储过程有多个OUT参数时,在Map中用不同key放入,如params.put("out1", null); params.put("out2", null); 执行后out1和out2即被填充。注意类型匹配,避免ClassCastException。
返回值为对象的技巧
若存储过程返回结果集,使用queryForList("procName", params); 对于单一对象用queryForObject。输出参数仍通过params Map获取,与resultClass无关,提高开发效率。
错误处理与事务
调用时包裹在try-catch,捕获SQLException。事务中使用sqlMapClient.startTransaction()确保一致性。日志记录params前后值,便于调试。
高级技巧:游标返回
存储过程返回游标时,resultClass设为List或自定义类,parameterMap中注册类型处理器。示例:<resultMap id="cursorMap" class="MyVO">...</resultMap>
性能优化
复用SqlMapClient实例,避免重复解析xml。批量调用用batch模式。参数缓存减少网络传输。
FAQ
Q: 如何处理存储过程无返回值只更新?
A: 用sqlMapClient.update("procId", params);
Q: 输出参数类型不匹配怎么办?
A: 在SqlMapConfig中注册自定义TypeHandler。
Q: 支持Oracle和MySQL吗?
A: 是,语法略有差异,Oracle用{call proc(?)}。
Q: 如何调试参数值?
A: 打印params.toString()前后对比。
Q: iBatis升级到MyBatis需要改什么?
A: 类似,用SqlSession和@Select注解。