mybatis之调用带输出参数的存储过程(Oracle)
作者:柳风123
创建一个存储过程
CREATE OR REPLACE PROCEDURE GET_QUESTIONNAIRE_CONTENT(QUESTIONNAIRE_ID_IN IN VARCHAR2, resultOut OUT CLOB) begin # 处理逻辑 resultOut = 'result....' end
SQL工具中调用存储过程
我使用的工具是navicat
在Navicat工具中调用存储过程。
declare V_questionid VARCHAR2(100) ; --输入参数 V_replay clob; --输出参数 BEGIN DBMS_OUTPUT.ENABLE(buffer_size => null) ; --设置缓存大小 V_questionid := '2079439a1d0a4287999e1f0c3cffade12'; --赋值 --调用存储过程,GET_QUESTIONNAIRE_CONTENT 为存储过程的名字 GET_QUESTIONNAIRE_CONTENT(V_questionid,V_replay); dbms_output.put_line(V_replay); --输出结果 end;
错误 [Err] ORA-20000: ORU-10027: buffer overflow, limit of 20000 bytes
缓存溢出。使用dbms_output.put_line(变量)时报出的错误,从上面也可以知道dbms_output.put_line默认的缓存大小20000bytes 。
解决方法:
在调用Oracle输出语句之前,先调用 DBMS_OUTPUT.ENABLE(buffer_size => null),表示输出buffer不受限制。
Mybatis调用存储过程
Mapper中定义方法
【QuestionMapper.java】
void callProcedureContent(Map<String,Object> args);
Service中调用
// 使用Map 来传参并接受返回结果 Map<String,Object> args=new HashMap<>(); args.put("questionnaireId","q121231123123");//问卷id args.put("sqlStr",null);//接受返回结果 // 对于此存储过程而言,不需要指定返回结果。 sqlStr 会被赋予 存储过程的out类型参数值 questionMapper.callProcedureContent(args); String result = (String)args.get("sqlStr"); //从map 中获取结果
配置映射文件
Oracle脚本
<!--问卷导出 存储过程 答案 --> <update id="callProcedureContent" statementType="CALLABLE" parameterType="map"> CALL GET_QUESTIONNAIRE_CONTENT( #{questionnaireId,mode=IN,jdbcType=VARCHAR},#{sqlStr,mode=OUT,jdbcType=CLOB,javaType=string}) </update>
SQLServer脚本
<!--问卷导出 存储过程 答案 --> <update id="callProcedureContent" statementType="CALLABLE" parameterType="map"> { CALL GET_QUESTIONNAIRE_CONTENT( #{questionnaireId,mode=IN,jdbcType=VARCHAR},#{sqlStr,mode=OUT,jdbcType=CLOB,javaType=string}) } </update>
调用存储过程和执行普通的sql文件大致相同,
需要注意一下几点:
1.statementType
: 必须设置为 CALLABLE
。默认值是 PREPARED 不需要设置
2.调用带 输出参数的存储过程时,参数必须存在以下额外属性。
mode
:必须设置( mode=OUT、mode=INOUT)jdbcType
:必须设置 (jdbcType=VARCHAR、jdbcType=INTEGER。。。。。。。)
3.使用 CALL
来调用存储过程
4.调用SQLserver的存储过程,必须使用{}
包裹起来,使用Oracle没有这个限制。
5.parameterType : 可以省略
存储过程传参不同,mybatis对应接受返回结果的方式也是各不相同。
如果存储过程中 没有使用 OUT
或者INOUT
参数。接受返回结果和普通的查询 Sql写法一致。
对于查询语句(select)语句可以使用实体类来接受返回结果,mybatis会自动进行字段映射。
<select id="id" statementType="CALLABLE" resultType="map"> CALL SELECT_PROCEDURE(#{id,mode=IN,jdbcType=VARCHAR}) </update>
如果开启了配置下划线映射驼峰标记的配置,会将数据库字段(下划线)映射为驼峰写法的字段(USER_NAME—>userName)
<setting name="mapUnderscoreToCamelCase" value="true" />
存储过程中使用了 OUT
、INOUT
类型的参数。即使使用 select 元素查询,实际上返回结果也是null (存储过程脚本就没有必要写在 select 元素中,可以使用update、delete 等元素)。
通常使用实体类或者map作为传入参数并接受返回结果。
<update id="id" statementType="CALLABLE" parameterType="map"> { CALL PROCEDURE_NAME( #{id,mode=IN,jdbcType=VARCHAR}) } </update>
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。