映射兩表之間的關係通過兩個<resultMap>和兩個<statement>元素來完成,用VO來描述兩表之間的關係在IBatis框架中,其實仍然是通過SQL來完成的。
怎樣用SQL來表達“一對多”和“多對一”的關係呢?可以利用主表的主鍵作爲從表的外鍵對從表查詢,得到的結果就是“一對多”的關係。那麼“多對一”呢?可以利用從表的外鍵對主表進行查詢,只能得到惟一的一條記錄。因此,必須首先做兩個SQL。
1. 用SQL描述關係
<statement id=”getAttackSolution”
parameterClass=”String”
resultMap=”get-attackSolution-result”>
select *
from fw_attacksolution
where parents_attack_event_code = #parents_attack_event_code#
</statement>
<statement id=”getPattackDocument”
parameterClass=”String”
resultMap=”get-pattackDocument-result”>
select *
from attack_document_parents
where parents_attack_event_code = #parents_attack_event_code#
</statement>
利用<statement>元素來完成兩句SQL語句,id爲“getAttackSolution”的一句,表示根據attack_document_parents表的主鍵到fw_attacksolution表中進行查詢,得到的是多條fw_attacksolution表中的記錄,這就是“一對多”的關係描述。id爲“getPattackDocument”的一句代碼,是根據parents_attack_event_code字段到attack_document_parents表中進行查詢,由於parents_attack_event_code字段是attack_document_parents表的主鍵,所以查詢結果必然只有一條,那這就可以表示“一對一”的關係。
2. 關係的對應
接着需要將這些SQL映射到對象上去。在PattackDocument VO中有一個變量屬性的類型爲List,名爲attackSolution,它表示了多個AttackSolution VO的集合,那麼這在SQL映射到對象的<resultMap>元素中怎麼表示呢?請看下面的代碼:
<resultMap id=”get-pattackDocument-result”
class=”struts.sample.cap11.sample1.entity.PattackDocument”>
<result property=”parents_attack_event_code” column=”parents_attack_event_code”/>
<result property=”pattack_mean” column=”pattack_mean”/>
<result property=”attackSolution”
column=”parents_attack_event_code” select=”getAttackSolution”/>
</resultMap>
和沒有關係對應的<resultMap>元素相比,多了一個select屬性,這個select屬性在關係映射中的作用非常大,通過select屬性指定的標識可以惟一找到一句查詢SQL,而這句查詢SQL就表達了“一對多”的關係。這段代碼的解釋可以是這樣的:如果有查詢返回的是“get-pattackDocument-result”所指定的VO,當將結果集寫入VO的變量屬性時,得到一個JDBC無法識別的List類型。於是底層框架就會查找select屬性所指定的查詢SQL語句。運行這個子查詢,並將子查詢的結果集寫入List,返回到VO的變量屬性attackSolution中。
在AttackSolution VO中還有一個pattackDocument的變量屬性,它的類型是PattackDocument,同樣也可以用<result>元素來聲明。
<resultMap id=”get-attackSolution-result”
class=”struts.sample.cap11.sample1.entity.AttackSolution”>
<result property=”attack_event_code” column=”attack_event_code”/>
<result property=”attack_mean” column=”attack_mean”/>
<result property=”attack_action” column=”attack_action”/>
<result property=”parents_attack_event_code” column=”parents_attack_event_code” />
<result property=”pattackDocument”
column=”parents_attack_event_code” select=”getPattackDocument”/>
</resultMap>
它的工作方式和之前所描述的沒有差別,惟一的區別是select屬性所指定的查詢SQL語句查詢結果必然是一條記錄,即一個對象實例。
可見,select屬性所指定的查詢SQL既可以是一個集合,也可以是一個對象。