ibatis雜集

基礎配置文件爲SqlMapConfig.xml,其中和Spring整合後,部分配置可以由spring託管
主要可用的元素爲:
1:typeAlias 別名,用於縮短後續xml中的配置的類名
<typeAlias alias="order" type="testdomain.Order"/>
2:sqlMap 用於配置所有的子xml映射文件
<sqlMap resource="examples/sqlmap/maps/Person.xml" />
3:properties元素 用於加載資源文件,類似spring,使用${driver}進行獲取值,也可以使用url屬性獲取本地其他目錄的xml文件
<properties resource=" examples/sqlmap/maps/SqlMapConfigExample.properties " />

sqlMap配置文件

主要配置是相關的parameterClass resultClass屬性,或者對應的<parameterMap> <resultMap>,同樣也可以使用<typeAlias alias>縮短使用
的類名,注意使用的id名稱是全局唯一的
其他的還包括緩存配置

配置xml標籤介紹
<statement>: 通用聲明,使用任何CRUD類型的SQL語句 .其中主要的子標籤如下<insert><update><delete><select>還包括動態的

<procedure>

最關鍵的還是sql語句,只要jdbc支持,並不依賴ibtais裏面特殊的語法,這點區別於hibernate,在xml中進行編寫時,也可以使用<![CDATA[]]>
進行特殊字符過濾

主鍵的生成,主要還是依賴數據庫的不同,可以使用<selectKey>在Oracle中加載序列預生成,其中注意
<selectKey resultClass="int" keyProperty="id" > keyProperty爲後續中所使用的變量名,在該標籤中編寫SQl語句
SELECT STOCKIDSEQUENCE.NEXTVAL AS ID FROM DUAL

存儲過程的調用,使用<procedure>元素,具體需要參考不同SQL的CallableStatement文檔

<parameterMap id="swapParameters" class="map" >
<parameter property="email1" jdbcType="VARCHAR" javaType="java.lang.String" mode="INOUT"/>
<parameter property="email2" jdbcType="VARCHAR" javaType="java.lang.String" mode="INOUT"/>
</parameterMap>
<procedure id="swapEmailAddresses" parameterMap="swapParameters" >
{call swap_email_address (?, ?)}
</procedure>

parameterClass屬性與parameterMap作用基本一致,前者使用Java類型,後者使用xml中的<parameterMap>配置映射,需要注意指定java類型需

要有對用的get/set方法用於訪問屬性

resultClass屬性與resultMap,類型上面的parameters,用於參數的返回封裝,主要根據Sql結果集的列名進行轉換,根據文檔描述,使用

resultMap性能和可操作性會更好一些

resultClass="xml" xmlResultName=”person” 用於生成對應的xml文件 person爲xml主節點,子標籤根據sql的列名生成

詳細介紹parameters和results
其中parameterMap並不常用,可以使用parameterClass
在Sql中,設置內嵌參數,其中-999999用於設置默認值,
(#id:NUMERIC:-999999#, #description:VARCHAR:NO_ENTRY#);

使用Java基本類型時,需要使用#value#獲取值,如:
<statement id=”insertProduct” parameter=”java.lang.Integer”>
select * from PRODUCT where PRD_ID = #value#
</statement>
也可以使用int代替java.lang.Integer

Map類型的輸入參數,可以用“map”來代替“java.util.Map" SQl中獲取時,可以直接獲取#key#

ResultMap. 使用ResultClass時,有可能性能會稍微差一些

使用基本類型的值獲取: 也是依據別名,常用的value或val
<statement id=”getProductCount” resultClass=”java.lang.Integer”>
select count(1) as value from PRODUCT
</statement>

Map類型的Result,只要設置resultClass=”java.util.HashMap”
<statement id=”getProductCount” resultClass=”java.util.HashMap”>
select * from PRODUCT
</statement>


可以通過配置<resultMap>與statement中的resultMap屬性,建立鏈式的Sql聯合查詢,....可能是2條Sql
<resultMap id=”get-product-result” class=”com.ibatis.example.Product”>
<result property=”category” column=”PRD_CAT_ID” select=”getCategory”/>
</resultMap>
<resultMap id=”get-category-result” class=”com.ibatis.example.Category”>
...
</resultMap>

<statement id=”getProduct” parameterClass=”int” resultMap=”get-product-result”>
select * from PRODUCT where PRD_ID = #value#
</statement>

<statement id=”getCategory” parameterClass=”int” resultMap=”get-category-result”>
select * from CATEGORY where CAT_ID = #value#
</statement>

id---resultMap--<result property="category" column=”PRD_CAT_ID” select=”getCategory”>-->id-->

這種方法都會執行2個SQL語句,容易發生N+1,最好使用SQL聯合查詢進行

查詢的優化:
基本的原則是,如果您需要訪問相關的對象,則使用聯合查詢。否則,使用延遲加載和字節碼增強選項的子查詢。

如果要緩存查詢結果,則使用子查詢(而不是聯合查詢)來緩存查詢結果。

建議不要使用java.sql.Date,最好使用java.util.Date代替。

iBATIS是面向對象,所以基本類型並不能直接使用,需要使用對應的封裝類

動態Mapped Statement 動態SQL配置

<isGreaterThan> 子標籤: 進行條件判斷,生成不同的SQL語句
<select id="dynamicGetAccountList" cacheModel="account-cache" resultMap="account-result" >
select * from ACCOUNT
<isGreaterThan prepend="and" property="id" compareValue="0">
where ACC_ID = #id#
</isGreaterThan>
order by ACC_LAST_NAME
</select>

如果傳入的id>0 : select * from ACCOUNT where ACC_ID = ?
如果傳入的id<0 : select * from ACCOUNT

<isNotNull> 子標籤,判斷非空情況
<isNotNull prepend="AND" property="firstName">
(ACC_FIRST_NAME = #firstName#
<isNotNull prepend="OR" property="lastName">
ACC_LAST_NAME = #lastName#
</isNotNull>
)
</isNotNull>

<dynamic prepend="where"> 用在上訴條件標籤中,會自動判斷添加不符合時,不進行條件
<statement id="someName" resultMap="account-result" >
select * from ACCOUNT
<dynamic prepend="where">
<isGreaterThan prepend="and" property="id" compareValue="0">
ACC_ID = #id#
</isGreaterThan>
<isNotNull prepend=”and" property="lastName">
ACC_LAST_NAME = #lastName#
</isNotNull>
</dynamic>
order by ACC_LAST_NAME
</statement>

常見的二元條件元素: 比將一個屬性值和一個靜態值或另一個屬性值比較,如果條件爲“真”,元素體的內容將被包括在查詢SQL語句中
<isEqual><isNotEqual><isGreaterThan><isGreaterEqual><isLessThan><isLessEqual>

常見的一元條件元素:一元條件元素檢查屬性的狀態是否符合特定的條件
<isPropertyAvailable><isNotPropertyAvailable><isNull><isNotNull><isEmpty><isNotEmpty>
Available: 爲屬性是否存在

其他元素:這些元素檢查參數對象是否存在,區別上面,是判斷對象是否存在,而不是對象的屬性
<isParameterPresent><isNotParameterPresent>

Iterate 集合的遍歷,常用於讀取List集合中的元素
<iterate prepend=”AND” property=”userNameList” open=”(” close=”)” conjunction=”OR”>
username=#userNameList[]#
</iterate>
常見的屬性
open - 整個遍歷內容體開始的字符串,用於定義括號(可選)
close -整個遍歷內容體結束的字符串,用於定義括號(可選)
conjunction - 每次遍歷內容之間的字符串,用於定義AND或OR(可選)

使用的時候需要注意代表List參數的[] 是必須的,用於標識爲List

簡單的動態SQL元素: 使用$$進行SQL字符串拼接

對於 <insert> <update> <delete> 在調用方法時,會自動根據Jdbc返回影響的結果

可以使用RowHandler 對iBATIS每行查詢的時候,對每個結果進行處理

queryForPaginatedList()方法常用於分頁


可以使用sqlMapClient.startBatch(); 執行批處理指令,注意數據並不會被馬上進行提交,
sqlMapClient.executeBatch();用於提交批處理,但是更推薦使用存儲過程來代替

調用存儲過程的語法
{ call max_in_example(?, ?) }
當然也可以直接簡化成
max_in_example(?, ?)

注:這裏的? 由ParameterMap配置的順序而成

一些iBATIS使用技巧:

XML參數:
可以在iBATIS中直接傳入xml文件:xml:<parameter><accountId>3</accountId></parameter>
<select id="getByXmlId" resultClass="Account" parameterClass="xml">...
引用參數一樣可以使用##獲取值

XML返回結果:
<select id="getByIdValueXml" resultClass="xml" xmlResultName="account">
這裏的account將會生成爲xml的root節點,返回的結果將會封裝成對應的子節點

調用的時候使用sqlMap.queryForObject方法,結果集將會是一個字符串,如果返回多個結果,需要進行特殊的處理,可以交給其他的xml類庫進

行處理

使用resultMap可以建立同時對一個對象的外鍵查詢方式,不過很有可能造成N+1的情況,按照需求進行編寫
<result property="orderList" select="Ch6.getOrderInfoList" column="accountId" />

RowHandler接口,可以用於大規模數據處理中,用於讀取後,就銷燬該對象
進行查詢的時候,也要使用對應的方法sqlMapClient.queryWithRowHandler()方法
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章