程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> iBATIS ResultMap基礎淺析

iBATIS ResultMap基礎淺析

編輯:關於JAVA

iBATIS ResultMap是我們學習iBATIS中非常重要的一個內容,在我個人看來,能否真正用好iBATIS的一個關鍵,這就是ResultMap。字面上理解,它就是結果集的映射,就是將返回的記錄逐個字段的映射賦值給對象的屬性上。其實如果沒有特殊需求的話我們完全可以使用ResultClass來代替它,因為如果字段與屬性一模一樣的話,查詢出來數據集會自動匹配到ResultClass指定的類的實例對象,如果字段名不在屬性中的話,那這個字段將不會被返回的實例體類對象接受,相當於沒有查詢出這個字段一樣的。

每個ResultMap都有一個自己的ID,如果你在sqlmap.config中沒有配置使用命名空間的話,那麼這個ResulteMap ID是全局(這點在所有的iBATIS配置元素都是一樣的),ResultMap一個重要的屬性的是class,它將決定這個ResultMap對應的實例的類,換句話講,它的作用是指出結果集要映射的數據類型。在extends屬性中可以設置它將要繼承的ResultMap,如果給他指定的了值,那麼它將會從super Resultmap繼承所的映射配置字段。定義如下:

﹤resultMaps﹥  
  ﹤resultMap id="DemoResultMap" class="Hashtable"﹥  
  ﹤/resultMap﹥  
﹤/resultMaps﹥

如果你有正確配置了iBATIS的XSD架構文件的話,那麼這時候就會提示resultMap的定義是不完全的。沒錯,接下來就是要定義Result元素。每一個result元素都是定義一個字段與數據類屬性對應的映射。在每一個result元素有比較多的屬性參數,其中property和column是必須的,其它的參數屬性都是可選的。所以我們在每一個resultMap中必須定義超過一個以上的result定義。通常以下的配置就可以完成基本的配置了。

﹤resultMaps﹥  
  ﹤resultMap id="DemoResultMap" class="Hashtable"﹥  
﹤result property="id" column="id"/﹥  
  ﹤/resultMap﹥  
﹤/resultMaps﹥

但如果你需要更多的要求的話,result map仍然能夠最大限度的滿足你。

◆columnIndex屬性提供了我們將數據集的第幾個下標字段映射到指定的數據對象屬性的方案,但是這種方式應該盡量的少用,你會發現這對我們以後的維護和可讀性會產生很大的副作用。

◆dbType屬性明確指出這個字段對應的數據庫的類型,大多數情況我很少會用到。

◆type屬性則明確指出這個字段將對應的數據對象屬性的數據類型,通常如果你想保證類型安全的話,設置這個屬性是很必要的。

◆resultMapping屬性則稍微復雜一些,它是用在一種場景下,如果一個數據類的屬性本身不是基元數據類型,而是一個復雜數據類型的話,那我們就不可能很簡單地給它一個簡單的result元素就了事了,還必須給他一個完整的resultMap。而resultMapping屬性就是為了完成這個功能而存在的。它的屬性值是一個已存在的resultMap的ID。

◆nullValue屬性就沒什麼好講的了,它是給出當這個字段的值為null的時候,它的默認值是多少。

◆select屬性同resultMapping一樣比較復雜一樣,先說一下它的屬性值必須是一個返回數據集合的查詢語句的ID,能配置這個屬性的數據類屬性可以是一個基元類型,復合類型,也可以是一個包括多條數據的集合類型,這些類型都行,沒有問題的。它的一處重要的存在意義就在於描述不同表之間的關系問題,通過本次的查詢,你想不通過join的手段從另一個表查詢相關字段的時候,你就可以使用select屬性。如下:

﹤resultMaps﹥  
  ﹤resultMap id="DemoResultMap" class="Hashtable"﹥  
﹤result property="id" column="id"/﹥  
﹤result property="Children" column="id" select="SELECT_Children"/﹥  
  ﹤/resultMap﹥  
     ﹤/resultMaps﹥  
     ﹤statements﹥  
  ﹤select id="SELECT_Children" resultClass="ChildrenObject"﹥  
SELECT * FROM Children WHERE ParentID = #id#  
  ﹤/select﹥  
     ﹤/statements﹥

這樣就可以做到不用通過編程的方式來表示不同表的關聯關系和數據讀取問題。但是這樣有可能存在一種問題,如果你每次都要讀取數據的時候,你會發現你會產生更多次的與數據庫交互的情況,並且即使你不是每次都需要這數據,那會不會造成數據讀取的浪費呢?接下來的lazyLoad屬性就為我們提供了第二種問題的解決方案了,那就是數據的延遲加載,沒錯,延遲加載可以大大改善數據訪問的性能,它只是要需的時候才去讀取這些數據,對於主從表關系的時候,這樣的方式可能是最好的解決方式了。

OK,關於ResultMap的介紹就先到此為止,接下來我要記錄一下,我在使用過程中遇到的一些問題:

一.在使用ResultMap的時候,你要特別注意,如果你在ResultMap中給出的配置字段,但是你返回的數據集的時候卻沒有返回這個字段,那程序將出拋出異常。但是相反的,如果你返回了一些字段,卻沒有在ResultMap給出配置定義的話,那麼那些字段將不會被處理而不會給你任何的提示,相當沒有查詢出這些字段。你要特別注意這個問題。

二.如果沒有特別需求的情況,我建議還是把數據類的屬性設計成與數據庫字段字一樣的比較,這樣如果一般情況下我們都可以不用寫這個ResultMap,事實上如果沒有這樣的特殊要求,那麼去寫這個ResultMap仍然是一件非常耗時,並且容易出錯的一份差事。

三.在使用lazyLoad的時候要特別注意,不是什麼類型的數據都可以lazyLoad的,只有是實現的IList的接口的類型,並且數據類的屬性定義為IList類型的字段才能被lazyLoad。(關於是否只有IList類型的屬性才能被lazyLoad的問題還需要探討一下,因為就我使用的經驗只有這種類型才可以,甚至是Generic版的IList都不支持)。而且你在使用它的時候,還不能把這個IList類型的屬性轉換成你真正的數據類型。因為在運行時,這個屬性會被包裝成一個動態的類型,這個動態類型仍然實現了IList接口,就是因為這個動態類型才擴展了我們可以lazyLoad的功能。這時候在程序中使用的是運行時的動態類型所以你沒辦法進行強類型轉換。

iBATIS ResultMap的基礎情況以及問題暫時沒有想到更多了,如果以後還有關於iBATIS ResultMap的問題,都會更新上來,也希望大家一起來指正我的一些錯誤和不足,一起完善。不要讓我的一些錯誤的實踐誤導了初學者,謝謝。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved