ibatis的<![CDATA]>,dynamic屬性和#,$的應用
<![CDATA[ ]]>的正確使用
ibatis作為一種半自動化的OR Mapping工具,其靈活性日益體現出來,越來越多的人都傾向於在項目中使用。由於Sql中經常有與xml規範相衝突的字元對xml對應檔的合法性造成影響。許多人都知道使用<![CDATA[ ]]>標記來避免衝突,但是在sql配置中有動態語句的時候,還是有一些細節需要特別注意的,不然是費心又費力。
在使用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>
dynamic的正確使用
dynamic可以去除第一個prepend="and"中的字元(這裡為and),從而可以協助你實現一些很實用的功能。具體情況如下:
1.使用dynamic
1.1 xml
select * from Person表 <dynamic prepend="where"> <isNotNull property="name" prepend="and"> name=#name# </isNotNull> <isNotNull property="sex" prepend="and"> sex=#sex# </isNotNull> </dynamic>
1.2 結果
當name、sex都非null時打出如下的sql語句:
select Person where (and) name= ? , and sex= ?
顯然name前的and被自動去除了,很方便吧。
2.不使用dynamic
2.1 xml
如果我把dynamic 去掉就會變的很噁心,如下:
select * from Person <isNotNull property="name" prepend="and"> name=#name# </isNotNull> <isNotNull property="sex" prepend="and"> sex=#sex# </isNotNull>
2.2 結果
當name、sex都非null時打出如下的sql語句:
select Person where and name= ? , and sex= ?
顯然name前多個and,sql語句錯誤。
3.總結
dynamic 會自動去除第一個 prepend="and中的內容(這裡為and),從而方便一些操作。
#和$的區別在Ibatis中我們使用SqlMap進行Sql查詢時需要引用參數,在參數引用中遇到的符號#和$之間的區分為,#可以進行與編譯,進行類型匹配,而$不進行資料類型匹配,例如:
select * from table where id = #id# ,其中如果欄位id為字元型,那麼#id#表示的就是'id'類型,如果id為整型,那麼#id#就是id類型。
select * from table where id = $id$ ,如果欄位id為整型,Sql語句就不會出錯,但是如果欄位id為字元型,那麼Sql語句應該寫成 select * from table where id = '$id$'