今天遇到这样一个需求:
使用mybatis调用oracle存储过程,需要动态调用。前台传不同的参数、调用不同的存储过程;
过程中写的mapper文件如下:
<select id="updateRet2" parameterType="java.util.Map" statementType="CALLABLE">
{
call ${spName}
<foreach collection="datas.entrySet()" index="key" item="ent" open="(" separator="," close=")">
<if test="ent == "?"">
#{ent,mode=OUT,jdbcType=LONGVARCHAR,javaType=java.lang.String}
</if>
<if test="ent != "?"">
#{ent,mode=IN,jdbcType=INTEGER,javaType=java.lang.String}
</if>
</foreach>
}
</select>
- 已知 mybatis 接口中可以传入多个参数,实验中 参数添不添加@param均可
- 已知 调用存储过程框架会将OUT类型的参数注入到参数map中
- 已知 mapper文件中调用sp要写 statementType="CALLABLE"
- 已知 此mapper文件不使用foreach,将数据写死,可以调用成功
但是无论如何,使用此mapper文件不能将OUT类型返回,深入debug mybatis框架发现框架中维护了一个Context,通过以上mapper文件会在boundSql过程中 会维护adiitionalParameter,其key为 "_frec**_en" 这对应真正的sql参数名,value为“_frec*_va”,这对应真正的sql参数值,因此OUT返回值返回不出来。。。。。。。一直以为框架的问题。。。。。
<select id="updateRet2" parameterType="java.util.Map" resultType="java.util.Map" statementType="CALLABLE">
{
call ${spName}
<foreach collection="datas.entrySet()" index="key" item="ent" open="(" separator="," close=")">
<if test="ent == "?"">
#{datas[${key}],mode=OUT,jdbcType=LONGVARCHAR,javaType=java.lang.String}
</if>
<if test="ent != "?"">
#{datas[${key}],mode=IN,jdbcType=INTEGER,javaType=java.lang.String}
</if>
</foreach>
}
</select>
终于得解,此问题耗时两天,,,,,,