ResultMap 是掌握 iBATIS 的關鍵。若資料庫欄位與物件屬性一致,可用 ResultClass 自動映射;但實務上常面臨欄位名不一、巢狀物件、多表關聯等情境,ResultMap 便不可或缺。
<resultMap id="UserResult" class="com.example.User">
<result property="id" column="user_id"/>
<result property="name" column="user_name"/>
</resultMap>
id:全域唯一識別(若未啟用命名空間)class:目標物件類型extends:繼承另一 ResultMap,複用映射定義| 屬性 | 用途 | 建議 |
|---|---|---|
columnIndex | 指定結果集第 N 欄位 | 少用,降低可讀性與維護性 |
dbType | 明確指定資料庫欄位型別 | 少用,通常自動推斷即可 |
type | 指定物件屬性 Java 型別 | 建議設定,確保型別安全 |
resultMap | 巢狀物件映射,值為另一 ResultMap id | 處理複雜物件關聯必備 |
nullValue | 欄位為 NULL 時的預設值 | 視業務需求設定 |
select | 關聯查詢,值為另一 select statement id | 解決多表關聯,配合 lazyLoad 延遲載入 |
<resultMap id="ParentMap" class="Parent">
<result property="id" column="id"/>
<result property="children" column="id" select="SELECT_CHILDREN"/>
</resultMap>
<select id="SELECT_CHILDREN" resultClass="Child">
SELECT * FROM children WHERE parent_id = #id#
</select>
加上 lazyLoad="true" 可延遲載入子集合,大幅改善主從表查詢效能。注意:僅支援實作 IList 介面的屬性(含泛型 IList<T>),且執行期會被包裝為動態代理型別,無法強制轉型為具體集合類別。
ResultMap 定義的欄位若查詢未回傳,會拋異常;反之查詢多出的欄位會被靜默忽略。ResultMap 的工作量與錯誤率。IList 型別屬性支援 lazyLoad,且執行期為動態代理,避免強制轉型。