ibatis 對象關係實現

hibernate 的強大在於完全的對象化,對於對象之間的關係解決的比較好,如1對1,1對多,多對1,以及多對多。當然也包括繼承關係。
    而ibatis這方面就比較遜色了,不過對於也支持簡單的關連查詢,如1對1,和1對多。對於一般的情況來說,這兩種已經足夠了,當然不能層疊更新是一個缺陷,看了半天文檔,也沒有找到對象之間的層疊更新,估計是不支持。
    以前的版本ibatis處理關連是通過執行兩次sql來實現的,如下的實例:

    一對多關聯:

<sqlMap namespace="User">  
<typeAlias alias="user" type="com.ibatis.sample.User"/>  
<typeAlias alias="address" type="com.ibatis.sample.Address"/>  
<resultMap id="get-user-result" class="user">  
<result property="id" column="id"/>  
<result property="name" column="name"/>  
<result property="sex" column="sex"/>  
<result property="addresses" column="id" select="User.getAddressByUserId"/>  
</resultMap>  
<select id="getUsers" parameterClass="java.lang.String" resultMap="get-user-result">  
<![CDATA[ 
select id,name,sex from t_user 
where id = #id# 
]]>  
</select>  
<select id="getAddressByUserId" parameterClass="int" resultClass="address">  
<![CDATA[ 
select address,zipcode 
from t_address 
where user_id = #userid# 
]]>  
</select>  
</sqlMap>
這裏通過在resultMap 中定義嵌套查詢getAddressByUserId,我們實現了關聯數據的讀取。
需要注意的是,這裏有一個潛在的性能問題,也就是所謂“n+1”Select問題。
一對一關聯:
對於這種情況,我們可以採用一次Select兩張表的方式,避免這樣的性能開銷(假設上面示例中,每個User 只有一個對應的Address記錄):
<resultMap id="get-user-result" class="user">  
<result property="id" column="id"/>  
<result property="name" column="name"/>  
<result property="sex" column="sex"/>  
<result property="address" column="t_address.address"/>  
<result property="zipCode" column="t_address.zipcode"/>  
</resultMap>  
<select id="getUsers" parameterClass="java.lang.String" resultMap="get-user-result">  
<![CDATA[ 
select * 
from t_user,t_address 
where t_user.id=t_address.user_id 
]]>  
</select>  
這裏通過在resultMap 中定義嵌套查詢getAddressByUserId,我們實現了關聯數據的讀取。
需要注意的是,這裏有一個潛在的性能問題,也就是所謂“n+1”Select問題。
一對一關聯:
對於這種情況,我們可以採用一次Select兩張表的方式,避免這樣的性能開銷(假設上面示例中,每個User 只有一個對應的Address記錄):
<resultMap id="get-user-result" class="user">  
<result property="id" column="id"/>  
<result property="name" column="name"/>  
<result property="sex" column="sex"/>  
<result property="address" column="t_address.address"/>  
<result property="zipCode" column="t_address.zipcode"/>  
</resultMap>  
<select id="getUsers" parameterClass="java.lang.String" resultMap="get-user-result">  
<![CDATA[ 
select * 
from t_user,t_address 
where t_user.id=t_address.user_id 
]]>  
</select>  

在現在的版本中,對於n+1問題,ibatis已經很好的解決了。如下的配置:
一對一

<resultMap id=”get-product-result” class=”com.ibatis.example.Product”>  
<result property=”id” column=”PRD_ID”/>  
<result property=”description” column=”PRD_DESCRIPTION”/>  
<result property=”category” resultMap=“get-category-result” />  
</resultMap>  
<resultMap id=”get-category-result” class=”com.ibatis.example.Category”>  
<result property=”id” column=”CAT_ID” />  
<result property=”description” column=”CAT_DESCRIPTION” />  
</resultMap>  
<select id=”getProduct” parameterClass=”int” resultMap=”get-product-result”>  
select *  
from PRODUCT, CATEGORY  
where PRD_CAT_ID=CAT_ID  
and PRD_ID = #value#  
</select>
可以使用內在的resultMap來解決此問題。
同樣一對多如下:

<sqlMap namespace="ProductCategory">  
<resultMap id=”categoryResult” class=”com.ibatis.example.Category” groupBy=”id”>  
<result property=”id” column=”CAT_ID”/>  
<result property=”description” column=”CAT_DESCRIPTION”/>  
<result property=”productList” resultMap=”ProductCategory.productResult”/>  
</resultMap>  
<resultMap id=”productResult” class=”com.ibatis.example.Product”>  
<result property=”id” column=”PRD_ID”/>  
<result property=”description” column=”PRD_DESCRIPTION”/>  
</resultMap>  
<select id=”getCategory” parameterClass=”int” resultMap=”categoryResult”>  
select C.CAT_ID, C.CAT_DESCRIPTION, P.PRD_ID, P.PRD_DESCRIPTION  
from CATEGORY C left outer join PRODUCT P  
on C.CAT_ID = P.PRD_CAT_ID  
where CAT_ID = #value#  
</select>  
</sqlMap>
注意,需要使用增加groupBy屬性來分類
如果想實現,延遲加載的情況:

<sqlMapConfig> 
  <settings lazyLoadingEnabled="true"  

在日誌中顯示sql語句 

log4j.logger.com.ibatis=DEBUG 
log4j.logger.com.ibatis.common.jdbc.SimpleDataSource=DEBUG 
log4j.logger.com.ibatis.common.jdbc.ScriptRunner=DEBUG 
log4j.logger.com.ibatis.sqlmap.engine.impl.SqlMapClientDelegate=DEBUG 


發佈了19 篇原創文章 · 獲贊 4 · 訪問量 35萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章