上次的項目,要求我用java代碼調用存儲過程,折騰了好久。最后總算成功了。發片帖子紀念下,也給不懂存儲過程的但是要調用的人一些提示
首先介紹下存儲過程(本人是不會寫的,但是目前能看懂)
-
create or replace procedure P_DAP_UNI_CUBE_INFO(V_CUBE_NAME IN VARCHAR2, --每個參數都有三部分 形參 in/out 類型, in是入參 ,out是返回的參數
-
V_TABLE_NAME IN VARCHAR2,
-
V_RETCODE OUT VARCHAR2,
-
V_RETINFO OUT VARCHAR2) is /看括號里面的參數
-
/*
-
************************************************************************* 后面不用看了我就粘了一半,反正不是我寫的
-
*名 稱 --%@NAME: P_DAP_UNI_CUBE_INFO
-
*功能描述 --%@COMMENT:
-
*執行周期 --%@PERIOD:
-
*參 數 --%@PARAM:ACCT_MONTH 帳期 YYMMDD
-
*參 數 --%@PARAM:V_RETCODE 過程執行結果代碼(成功:SUCCESS/失敗:FAIL/等待:WAIT),輸出參數
-
*參 數 --%@PARAM:V_RETINFO 過程執行結果描述,輸出參數
-
*創 建 人 --%@CREATOR:
-
*創建時間 --%@CREATED_TIME: 2018-3-12
-
*備 注 --%@REMARK:
-
*修改記錄 --%@MODIFY: 修改人 YYYYMMDD 修改內容
-
*來 源 表 --%@FROM:
-
*目 標 表 --%@TO:
-
**************************************************************************
-
*/
-
V_PROV_ID VARCHAR2(3);
-
V_PKG VARCHAR2(40);
-
V_PROCNAME VARCHAR2(50);
-
V_ROWLINE NUMBER := 0; -- 記錄目標表數據變化記錄數
-
V_CUBE_ID VARCHAR2(100);
-
V_FILEDATE VARCHAR2(100);
上面就是數據庫里已經存在的 存儲過程了。有4個參數,前兩個是輸入,后兩個是輸出。假如直接從plsql調用,可以這么寫

然后點旁邊的輸出就能看到結果;
你需要在plsql能調用成功的情況下才能使用代碼調用
用mybatis調用時候的xml文件
-
<select id="addCubeSqlMap" parameterType="java.util.Map" statementType="CALLABLE" >
-
{CALL jzyx_label.P_DAP_UNI_CUBE_INFO
-
(#{V_CUBE_NAME,mode=IN,jdbcType=VARCHAR},
-
#{V_TABLE_NAME,mode=IN,jdbcType=VARCHAR},
-
#{V_RETCODE,mode=OUT,jdbcType=VARCHAR},
-
#{V_RETINFO,mode=OUT,jdbcType=VARCHAR}
-
)}
-
</select>
大概就是select標簽里面 call 存儲過程名(參數1,參數2,參數3……)
雖然寫了四個參數,但是其實你傳過來的map只需要封裝入參(就是mode=in)的就好了
mapper層
-
// 執行 存儲過程
-
public int addCubeSqlMap(Map <String,String> sql);
String cubeName = "第一個入參";
String factTableName = "第二個入參";
Map<String,String > parm = new HashMap<String,String>();
parm.put("V_CUBE_NAME",cubeName);
parm.put("V_TABLE_NAME",factTableName);
evapMapper.addCubeSqlMap(parm);
反正在map里面放入兩個入參,傳過去就能執行儲存過程。
我當時不需要存儲過程的返回值就沒有取,如果要取存儲過程的返回值直接用這個map去get就拿到了假設我要取這個過程的參數應該這么寫
-
evapMapper.addCubeSqlMap(parm); //接着上面的代碼
-
parm.get("V_RETCODE"); //直接get你要傳入xml的map get mode=out 的那個參數名就拿到了存儲過程給你返回的值……是不是很奇妙
-
parm.get(" V_RETINFO");
---------------------------------分隔線
當時遇到的一個錯誤,貼出來警告自己,為什么那么蠢

---------------------分割線
Mybatis調用數據庫的存儲過程和方法
定義一個存儲過程:
- create or replace procedure prg_add(p1 in number,p2 in number,p3 out number)
- as
- begin
- p3:=p1+p2;
- end;
定義一個方法:
- create or replace function fun_add(p1 number, p2 number)
- return number
- as
- begin
- return p1+p2;
- end;
java中的sql調用語句:
String sql="{call 存儲過程名(?,?,?)}"
Register(3,Number);
String sql="{?=call 函數名(?,?)}"
jdbc.properties:
- url=jdbc\:oracle\:thin\:@localhost\:1521\:orcl
- driverClass=oracle.jdbc.OracleDriver
- account=scott
- password=tiger
mybatis.xml:
- <?xml version="1.0" encoding="UTF-8" ?>
- <!DOCTYPE configuration
- PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
- "http://mybatis.org/dtd/mybatis-3-config.dtd">
- <configuration>
- <properties resource="cn/et/mybatis/lesson01/jdbc.properties">
- </properties>
- <!--
- 配置連接數據庫的環境 development開發環境
- -->
- <environments default="development">
- <environment id="development">
- <!-- 事務交給JDBC來管理 也就是通過 Connection的 commit和rollback管事事務 -->
- <transactionManager type="JDBC"/>
- <dataSource type="POOLED">
- <property name="driver" value="${driverClass}"/>
- <property name="url" value="${url}"/>
- <property name="username" value="${account}"/>
- <property name="password" value="${password}"/>
- </dataSource>
- </environment>
- </environments>
- <mappers>
- <mapper resource="cn/et/mybaits/lesson02/func/call_mapper.xml" />
- </mappers>
- </configuration>
call_mapper.xml:
- <?xml version="1.0" encoding="UTF-8" ?>
- <!DOCTYPE mapper
- PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
- "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
- <!--
- 接口映射
- namespace必需跟接口的全名一致
- -->
- <mapper namespace="cn.et.mybaits.lesson02.func.CallMapper">
- <!-- statementType: STATEMENT就是搞sql語句 CALLABLE就是搞存儲過程和函數-->
- <select id="callProcedure" parameterType="map" statementType="CALLABLE">
- {
- call prg_add(
- #{p1,mode=IN,jdbcType=NUMERIC},
- #{p2,mode=IN,jdbcType=NUMERIC},
- #{p3,mode=OUT,jdbcType=NUMERIC}
- )
- }
- </select>
- <select id="callFunction" parameterType="map" statementType="CALLABLE">
- {
- #{p3,mode=OUT,jdbcType=NUMERIC}=call fun_add(
- #{p1,mode=IN,jdbcType=NUMERIC},
- #{p2,mode=IN,jdbcType=NUMERIC}
- )
- }
- </select>
- </mapper>
CallMapper接口:
- package cn.et.mybaits.lesson02.func;
- import java.util.Map;
- public interface CallMapper {
- public void callProcedure(Map map);
- public void callFunction(Map map);
- }
TestMabatis.Java:
- package cn.et.mybaits.lesson02.func;
- import java.io.InputStream;
- import java.util.HashMap;
- import java.util.List;
- import java.util.Map;
- import org.apache.ibatis.session.SqlSession;
- import org.apache.ibatis.session.SqlSessionFactory;
- import org.apache.ibatis.session.SqlSessionFactoryBuilder;
- import org.junit.Test;
- public class TestMybatis {
- public static SqlSession getSession(){
- String resource = "/cn/et/mybaits/lesson02/mybatis.xml";
- InputStream inputStream = TestMybatis.class.getResourceAsStream(resource);
- SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
- //打開會話
- SqlSession session = sqlSessionFactory.openSession();
- return session;
- }
- /* public static void main(String[] args) {
- SqlSession session = getSession();
- CallMapper cm = session.getMapper(CallMapper.class);
- Map map = new HashMap();
- map.put("p1", 145);
- map.put("p2", 100);
- cm.callProcedure(map);
- System.out.println(map.get("p3"));
- }
- */
- public static void main(String[] args) {
- SqlSession session = getSession();
- CallMapper cm = session.getMapper(CallMapper.class);
- Map map = new HashMap();
- map.put("p1", 1243);
- map.put("p2", 1000);
- cm.callFunction(map);
- System.out.println(map.get("p3"));
- }
- }
