mybatis之調(diào)用帶輸出參數(shù)的存儲過程(Oracle)
創(chuàng)建一個存儲過程
CREATE OR REPLACE PROCEDURE GET_QUESTIONNAIRE_CONTENT(QUESTIONNAIRE_ID_IN IN VARCHAR2, resultOut OUT CLOB) begin # 處理邏輯 resultOut = 'result....' end
SQL工具中調(diào)用存儲過程
我使用的工具是navicat
在Navicat工具中調(diào)用存儲過程。
declare V_questionid VARCHAR2(100) ; --輸入?yún)?shù) V_replay clob; --輸出參數(shù) BEGIN DBMS_OUTPUT.ENABLE(buffer_size => null) ; --設(shè)置緩存大小 V_questionid := '2079439a1d0a4287999e1f0c3cffade12'; --賦值 --調(diào)用存儲過程,GET_QUESTIONNAIRE_CONTENT 為存儲過程的名字 GET_QUESTIONNAIRE_CONTENT(V_questionid,V_replay); dbms_output.put_line(V_replay); --輸出結(jié)果 end;
錯誤 [Err] ORA-20000: ORU-10027: buffer overflow, limit of 20000 bytes
緩存溢出。使用dbms_output.put_line(變量)時報出的錯誤,從上面也可以知道dbms_output.put_line默認(rèn)的緩存大小20000bytes 。
解決方法:
在調(diào)用Oracle輸出語句之前,先調(diào)用 DBMS_OUTPUT.ENABLE(buffer_size => null),表示輸出buffer不受限制。
Mybatis調(diào)用存儲過程
Mapper中定義方法
【QuestionMapper.java】
void callProcedureContent(Map<String,Object> args);
Service中調(diào)用
// 使用Map 來傳參并接受返回結(jié)果 Map<String,Object> args=new HashMap<>(); args.put("questionnaireId","q121231123123");//問卷id args.put("sqlStr",null);//接受返回結(jié)果 // 對于此存儲過程而言,不需要指定返回結(jié)果。 sqlStr 會被賦予 存儲過程的out類型參數(shù)值 questionMapper.callProcedureContent(args); String result = (String)args.get("sqlStr"); //從map 中獲取結(jié)果
配置映射文件
Oracle腳本
<!--問卷導(dǎo)出 存儲過程 答案 --> <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腳本
<!--問卷導(dǎo)出 存儲過程 答案 --> <update id="callProcedureContent" statementType="CALLABLE" parameterType="map"> { CALL GET_QUESTIONNAIRE_CONTENT( #{questionnaireId,mode=IN,jdbcType=VARCHAR},#{sqlStr,mode=OUT,jdbcType=CLOB,javaType=string}) } </update>
調(diào)用存儲過程和執(zhí)行普通的sql文件大致相同,
需要注意一下幾點(diǎn):
1.statementType
: 必須設(shè)置為 CALLABLE
。默認(rèn)值是 PREPARED 不需要設(shè)置
2.調(diào)用帶 輸出參數(shù)的存儲過程時,參數(shù)必須存在以下額外屬性。
mode
:必須設(shè)置( mode=OUT、mode=INOUT)jdbcType
:必須設(shè)置 (jdbcType=VARCHAR、jdbcType=INTEGER。。。。。。。)
3.使用 CALL
來調(diào)用存儲過程
4.調(diào)用SQLserver的存儲過程,必須使用{}
包裹起來,使用Oracle沒有這個限制。
5.parameterType : 可以省略
存儲過程傳參不同,mybatis對應(yīng)接受返回結(jié)果的方式也是各不相同。
如果存儲過程中 沒有使用 OUT
或者INOUT
參數(shù)。接受返回結(jié)果和普通的查詢 Sql寫法一致。
對于查詢語句(select)語句可以使用實(shí)體類來接受返回結(jié)果,mybatis會自動進(jìn)行字段映射。
<select id="id" statementType="CALLABLE" resultType="map"> CALL SELECT_PROCEDURE(#{id,mode=IN,jdbcType=VARCHAR}) </update>
如果開啟了配置下劃線映射駝峰標(biāo)記的配置,會將數(shù)據(jù)庫字段(下劃線)映射為駝峰寫法的字段(USER_NAME—>userName)
<setting name="mapUnderscoreToCamelCase" value="true" />
存儲過程中使用了 OUT
、INOUT
類型的參數(shù)。即使使用 select 元素查詢,實(shí)際上返回結(jié)果也是null (存儲過程腳本就沒有必要寫在 select 元素中,可以使用update、delete 等元素)。
通常使用實(shí)體類或者map作為傳入?yún)?shù)并接受返回結(jié)果。
<update id="id" statementType="CALLABLE" parameterType="map"> { CALL PROCEDURE_NAME( #{id,mode=IN,jdbcType=VARCHAR}) } </update>
總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
Java實(shí)現(xiàn)定時任務(wù)的方法總結(jié)
這篇文章主要為大家詳細(xì)介紹了Java中實(shí)現(xiàn)定時任務(wù)的常用7中方法,文中的示例代碼講解詳細(xì),具有一定的借鑒價值,需要的小伙伴可以參考一下2023-06-06Java 面向?qū)ο笾^承篇詳解原理與特點(diǎn)
繼承是java面向?qū)ο缶幊碳夹g(shù)的一塊基石,因為它允許創(chuàng)建分等級層次的類。繼承就是子類繼承父類的特征和行為,使得子類對象(實(shí)例)具有父類的實(shí)例域和方法,或子類從父類繼承方法,使得子類具有父類相同的行為2021-10-10淺談java線程中生產(chǎn)者與消費(fèi)者的問題
下面小編就為大家?guī)硪黄獪\談java線程中生產(chǎn)者與消費(fèi)者的問題。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2016-07-07Java如何找出數(shù)組中重復(fù)的數(shù)字
這篇文章主要為大家詳細(xì)介紹了Java如何找出數(shù)組中重復(fù)的數(shù)字,具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-08-08關(guān)于SpringBoot的spring.factories文件詳細(xì)說明
spring.factories 文件是 Spring Boot 自動配置機(jī)制的核心部分之一,它位于每個 Spring Boot 自動配置模塊的 META-INF 目錄下,經(jīng)??吹?nbsp;spring.factories 文件,卻沒有對它進(jìn)行深入的了解和分析,今天我們就一起揭開面紗看看它的內(nèi)在,需要的朋友可以參考下2024-12-12分析設(shè)計模式之模板方法Java實(shí)現(xiàn)
所謂模板方法模式,就是一個對模板的應(yīng)用,就好比老師出試卷,每個人的試卷都是一樣的,這個原版試卷就是一個模板,可每個人寫在試卷上的答案都是不一樣的,這就是模板方法模式。它的主要用途在于將不變的行為從子類搬到超類,去除了子類中的重復(fù)代碼2021-06-06關(guān)于Scanner對象的輸入結(jié)束標(biāo)記問題
這篇文章主要介紹了關(guān)于Scanner對象的輸入結(jié)束標(biāo)記問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-05-05