ibatis中使用List作為傳入參數的使用方法及 CDATA使用


ibatis中list做回參很簡單,resultClass設為list中元素類型,dao層調用:

(List)getSqlMapClientTemplate().queryForList("sqlName", paraName);  

並經類型轉換即可,做入參還需要稍微調整下,本文主要講list做入參碰到的幾個小問題:

入參主要有兩種方法一種是以list直接作為入參,另一種是將list作為map的元素之一為入參,個人覺得第一種明顯優勢,就一個list為入參,還用map包裝一層多蛋疼。下面的介紹都以這個sql為例

 "getProjectJobIdsByProjectIds" resultClass="java.lang.Integer"  
    parameterClass="java.util.ArrayList">  
      
    SELECT id   
    FROM cic_job   
    WHERE last_buildid <> 'NULL'  
      
    "AND" open="(" close=")" conjunction="or">  
        CRID=#projectIdList[]#  

以上是正確的寫法,意義大家不用關注,重點放在倒數2到4行,表示以list為入參,其中projectIdList為dao層傳入的參數名。主要寫法就是parameterClass="java.util.ArrayList",然后加上

"AND" open="(" close=")" conjunction="or">  
CRID=#projectIdList[]#  

意思就是迭代器循環projectIdList,並用or拼接形成sql,拼接完后用()括起來,在加上前綴and。

1、iterate property的問題

網上很多寫法是:

property="projectIdList" prepend="AND" open="(" close=")" conjunction="or">  

即多了一個property,這個時候ibatis會從參數中尋找屬性為projectIdList的對象,而list是一個對象沒有屬性就會報錯:

Cause: com.ibatis.common.beans.ProbeException: Error getting ordinal list from JavaBean. 
Cause java.lang.StringIndexOutOfBoundsException: String index out of range: -1

異常,解決方法就是去掉property="projectIdList"

其實這種寫法是相對第二種以map為參數而言的,你可以使用map傳入參數設置屬性為 property對應名即可。

2、< ! [ CDATA[的問題

大家注意到上面sql添加有 ! [ CDATA[,它的作用是對一些字符進行轉移,具體可以參見http://renren.it/a/JAVAbiancheng/iBATIS/20111105/139874.html

但上面sql如果寫成:

 <select id="getProjectJobIdsByProjectIds" resultClass="java.lang.Integer"  
    parameterClass="java.util.ArrayList">  
    <![CDATA[  
    SELECT id   
    FROM cic_job   
    WHERE last_buildid <> 'NULL'  
    <iterate prepend="AND" open="(" close=")" conjunction="or">  
        CRID=#projectIdList[]#  
        </iterate>  
    ]]>  
</select> 

擴大轉義范圍會出現如下錯誤:

com.ibatis.common.beans.ProbeException: There is no READABLE property named 'projectIdList[]' in class 'java.util.ArrayList' 

解決方法,就是縮小 CDATA的范圍。原因是CDATA導致系統無法識別動態判斷部分。

在使用ibatis時,經常需要配置待執行的sql語句。使用過ibatis的朋友都知道,無可避免的都會碰到一些不兼容、沖突的字符,多數人也都 知道用<![CDATA[  ]]>標記避免Sql中與xml規范相沖突的字符對xml映射文件的合法性造成影響。但是,如果在ibatis中使用了動態語句的時候,還是有一些 細節需要注意。下面舉例說明一下:

環境:oracle、ibatis、java

錯誤例1:符號“<=”會對xml映射文件的合法性造成影響

<select id="find" parameterClass="java.util.Map" resultClass="java.lang.Long">  

select id

from tableA a,

     tableB b

 <dynamic prepend="WHERE">

 <isNotNull prepend="AND" property="startDate">

  a.act_time >= #startDate# 

  and a.act_time <= #endDate#

  and a.id = b.id 

 </isNotNull>    

 </dynamic>  

</select>

錯誤例2:將整個sql語句用<![CDATA[  ]]>標記來避免沖突,在一般情況下都是可行的,但是由於該sql配置中有動態語句(where部分),將導致系統無法識別動態判斷部分,導致整個sql語句非法。

<select id="find" parameterClass="java.util.Map" resultClass="java.lang.Long">

< ![CDATA[   

select id

from tableA a,

     tableB b

 <dynamic prepend="WHERE">

 <isNotNull prepend="AND" property="startDate">

  a.act_time >= #startDate# 

  and a.act_time <= #endDate#

  and a.id = b.id 

 </isNotNull>    

 </dynamic>  

  ]]>

</select>

正確做法:縮小范圍,只對有字符沖突部分進行合法性調整。

<select id="find" parameterClass="java.util.Map" resultClass="java.lang.Long">  

select id

from tableA a,

     tableB b

 <dynamic prepend="WHERE">

 <isNotNull prepend="AND" property="startDate">

  a.act_time >= #startDate# 

  < ![CDATA[ and a.act_time <= #endDate#  ]]>

  and a.id = b.id 

 </isNotNull>    

 </dynamic>  

</select>
------------------------------------------------------------------

ibatis中應該經常見到"<![CDATA["這樣的東西吧,它的用處應該是轉義一些特殊關鍵字字符,不合法的XML字符必須被替換為相應的實體。 下面是五個在XML文檔中預定義好的實體:

< &gt;  小於號
> &lt;  大於號
& &
&apos; ' 單引號
" " 雙引號

一個 CDATA 部件以"< ! [CDATA[" 標記開始,以"]]>"標記結束:

<message>if salary < 1000 then</message>

為了避免出現這種情況,必須將字符"<" 轉換成實體,象下面這樣:

<message>if salary < 1000 then</message>

這里有一個問題,由於我在ibatis中用到了一個循環標簽"<iterate>" ,為了寫一個  類似

SELECT * FROM b 

WHERE b.trade_no in
 <iterate property="tradeNoList" open="(" close=")" conjunction=",">#tradeNoList[]#</iterate>
   AND .........這樣的一個語句。

由於"<iterate"標簽以 "<"開頭,那么可能被"< ! [CDATA["轉義了,所以造成語法錯誤,sql不能正常執行,去掉"<![CDATA["后發現sql能正常執行。

所以在碰到類似問題的時候,應該留意,在"< ! [CDATA["轉義符中間不要用標簽。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM