最近開始接觸Oracle了,接觸的越多越感受到自己的渺小!(oracle10g ,Ibatis)
昨天需要通過數據庫查詢一組數據,數據中包含一個表中的一條數據、2個String類型的字符串,想通過Oralce的存儲過程實現。
ibatis映射配置:
<parameterMap id="parameterDJRYID" class="java.util.HashMap" >
<parameter property="v_ryid" jdbcType="INTEGER" javaType="java.lang.Integer" mode="IN"/> //存儲過程傳入參數
<parameter property="PYR_IDS" jdbcType="VARCHAR" javaType="java.lang.String" mode="OUT" /> //存儲過程傳出參數
<parameter property="PYR_XMS" jdbcType="VARCHAR" javaType="java.lang.String" mode="OUT"/> //存儲過程傳出參數
<parameter property="MY_CUR" jdbcType="ORACLECURSOR" javaType="java.sql.ResultSet" mode="OUT"/> //存儲過程傳出參數
</parameterMap>
<procedure id="P_DJ_GETRYANDPYRBYRYID" parameterMap="parameterDJRYID" resultClass="java.util.HashMap">
{call P_DJ_GETRYANDPYRBYRYID(?)} //我的存儲過程
</procedure>
Service類調用Ibatis的代碼:
Map paramMap = new HashMap();
paramMap.put("v_ryid", primaryKey);
List <DjRy> list = DBUtil.getObjectList("T_Dj_Ry.P_DJ_GETRYANDPYRBYRYID", paramMap); //這個是我們自己封裝的工具,主要操作Ibatis,這裏可以看成Ibatis查詢並返回List結果。
Map<String, Object> map = new HashMap<String, Object>();
map.put("PYR_IDS", paramMap.get("PYR_IDS")); //傳回的兩個參數
map.put("PYR_XMS", paramMap.get("PYR_XMS"));
map.put("MY_CUR", list);
至於我的存儲過程就不寫出來了,沒什麼需要特殊寫明的,只是數據庫的一些關聯查詢,比較麻煩,就不貼出來了。
運行起來後,沒成功。。。。
提示的錯誤信息要求檢查輸出類型:
--- Check the output parameters (register output parameters failed).
--- Cause: java.sql.SQLException: 無效的列類型
在Google上百度了一下,大部分的人問題的原因都是在Ibatis映射配置時,傳入傳出的參數中jdbcType與JavaType的類型不正確,可是我多番驗證,我的類型是正確的。同時我將傳出的參數一個個的減少,直到沒有傳出參數才能正常運行。真的鬱悶了。。。。
經過幾個小時的糾結,終於發現問題的所在了。
在Ibatis映射配置中,當我調用存儲過程中,需要使用?進行參數的佔位符,而這個參數不能只寫入參,還要寫出參。。。。
也就是說,我的Ibatis映射配置中調用存儲過程的代碼應該這樣寫:
{call P_DJ_GETRYANDPYRBYRYID(?,?,?,?)}
欲哭無淚啊!!!!
這樣程序終於運行起來了,生活還要繼續,問題還要繼續產生啊!
現在是能夠在數據庫端將數據返回了,返回的結果是2個String類型的字符串,一個結果集。現在我要實現的效果是將結果集給一個list<DjRy>(DjRy是我的Javabean類),那2個字符串就不用理會了。
可是我怎麼給,DjRy這個類都不接受!出錯了。。。
糾結一番,明白了。
原來我在Ibatis映射配置中,定義的存儲過程的返回值爲HashMap(下面紅色的字體)
<procedure id="P_DJ_GETRYANDPYRBYRYID" parameterMap="parameterDJRYID" resultClass="java.util.HashMap">
{call P_DJ_GETRYANDPYRBYRYID(?,?,?,?)} //我的存儲過程
</procedure>
而這個返回值只是指我3個返回值中結果集的返回值,所以說我返回的結果集是以Hashmap的類型存在的,當我將list中的每一個元素給javabean時,就會發生類型轉換錯誤。
此處需要將定義存儲過程的代碼改爲:
<procedure id="P_DJ_GETRYANDPYRBYRYID" parameterMap="parameterDJRYID" resultMap="DjRyResult">
{call P_DJ_GETRYANDPYRBYRYID(?,?,?,?)}
</procedure>
DjRyResult就是我的Ibatis中針對DjRy定義的resultMap。這樣我就可以將返回的結果集傳遞給DjRy的List中進行遍歷了。
還有我的paramMap中在數據庫操作之前需要將參數存入,在操作數據庫之後,paramMap中會存放返回值中非結果集的參數(包括入參、出參),而在ibatis中定義的出參MY_CUR其實在paramMap中是null值,而list中存放的卻是我的結果集返回值。所以在獲取返回的參數時,纔會按照下面的方式進行:
map.put("PYR_IDS", paramMap.get("PYR_IDS")); //傳回的兩個參數
map.put("PYR_XMS", paramMap.get("PYR_XMS"));
map.put("MY_CUR", list);
這樣也產生了新的問題,當我們在開發過程中,如果要返回2個結果集(或者說存儲過程中,要返回2個遊標),又要怎麼處理呢?這個還真沒想到!誰要是知道,互相交流一下啊!
真不容易啊,就這些弄了一天,落後就要折騰啊!