在資料庫中比較常見一對一、一對多的資料,本文將敘述如何用多種方式實現這些關聯關係,並對這些方法進行比對和分析。
例子假設的情境如下:
有兩張表:product(產品)、category(種類),一個產品只屬於某一個種類,但某一個種類下可以有多個產品。
一對一
情境:
查詢某個產品,並列示出該產品所屬的種類。
實現一對一的關係有兩種方式。
方式一:
<sqlMap namespace="one-to-one"><resultMap class="com.ibatis.example.domain.Product" id="get-product-result"><result property="id" column="PRD_ID" /><result property="description" column="PRD_DESCRIPTION" /><result property="category" column="PRD_CAT_ID" select="one-to-one.getCategory" /></resultMap><resultMap class="com.ibatis.example.domain.Category" id="get-category-result"><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 where PRD_ID = #value#</select><select id="getCategory" parameterClass="int" resultMap="get-category-result">select *from CATEGORY where CAT_ID = #value#</select></sqlMap>
方式二:
<sqlMap namespace="one-to-one-v2"><resultMap class="com.ibatis.example.domain.Product" id="get-product-result"><result property="id" column="PRD_ID" /><result property="description" column="PRD_DESCRIPTION" /><result property="category.id" column="CAT_ID" /><result property="category.description" column="CAT_DESCRIPTION" /></resultMap><select id="getProduct" parameterClass="int" resultMap="get-product-result">selectt1.prd_id, t1.prd_description, t2.cat_id, t2.cat_descriptionfromproduct t1, category t2 where t1.prd_cat_id = t2.cat_id and t1.prd_id= #value#</select></sqlMap>
比對:
1、方式一結構劃分更加清晰,可重用性更好。
2、方式二效能更高,實際上是方式一的改進。因為在方式一中,查詢一次product表,會額外地查詢一次category,這樣實際上訪問了資料庫兩次。但方式二利用聯集查詢,很好地避免了這個問題。
一對多
情境:
查詢某個種類,並列出該種類下的所有產品。
實現一對多的關係有兩種方式。
方式一:
<sqlMap namespace="one-to-many"><resultMap class="com.ibatis.example.domain.Category" id="get-category-result"><result property="id" column="CAT_ID" /><result property="description" column="CAT_DESCRIPTION" /><result property="products" column="CAT_ID" select="one-to-many.getProductByCatId" /></resultMap><resultMap class="com.ibatis.example.domain.Product" id="get-product-result"><result property="id" column="PRD_ID" /><result property="description" column="PRD_DESCRIPTION" /></resultMap><select id="getProductByCatId" parameterClass="int"resultMap="get-product-result">select *from PRODUCT where PRD_CAT_ID = #value#</select><select id="getCategory" parameterClass="int" resultMap="get-category-result">select *from CATEGORY where CAT_ID = #value#</select></sqlMap>
方式二:
<sqlMap namespace="one-to-many-v2"><resultMap class="com.ibatis.example.domain.Category" id="get-category-result"groupBy="id"><result property="id" column="CAT_ID" /><result property="description" column="CAT_DESCRIPTION" /><result property="products" column="CAT_ID"resultMap="one-to-many-v2.get-product-result" /></resultMap><resultMap class="com.ibatis.example.domain.Product" id="get-product-result"><result property="id" column="PRD_ID" /><result property="description" column="PRD_DESCRIPTION" /></resultMap><select id="getCategory" parameterClass="int" resultMap="get-category-result">selectt1.prd_id, t1.prd_description, t2.cat_id, t2.cat_description fromproduct t1, category t2 where t1.prd_cat_id = t2.cat_id and t2.CAT_ID= #value#</select></sqlMap>
比對:
1、方式一結構更好,但是在查詢時除了查詢種類表,還會去查詢產品表。如果是有多個種類表,則會多次去查詢產品表。
2、方式二是方式一的一種改進,通常來講效能會更好一些。它是執行聯集查詢,將資料查詢出來後,再根據groupBy關鍵字對資料進行歸類。
ibatis支援消極式載入,如果對種類下的產品不是特別關注,可以設定消極式載入,在使用到種類對應的產品時再去查詢資料庫。如果極少使用到種類對應的產品,很明顯方式一會更加高效。
在具體使用時,需要根據實際情況來決定採用何種方式。
執行個體代碼可參考:
http://download.csdn.net/detail/duwenchao1986/5048568