iBATISNET資料_第1頁
iBATISNET資料_第2頁
iBATISNET資料_第3頁
iBATISNET資料_第4頁
iBATISNET資料_第5頁
已閱讀5頁,還剩21頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

1、.; HYPERLINK http:/ ibatisnet系列(一) 總覽廢話一翻后,進入今天的正題。今天的主題是Introduction,非官方正式介紹的中文版,更多詳細的介紹請參閱官方文檔。我們要使用它就必須要知道它是干什么用的,能為我們做哪些工作,開發(fā)效率如何,執(zhí)行效率如何,技術(shù)難度怎么樣。提到iBatis,大家可能會與ORM技術(shù)聯(lián)系起來。是的,沒錯,它與ORM技術(shù)有一定程度上的聯(lián)系,但是更確切地講,它并不是一種很正統(tǒng)的ORM解決方案。因為它不像NHibernate那樣,具備全自動的數(shù)據(jù)操作,包括查詢,插入,更新,刪除;也沒有像它那樣,與數(shù)據(jù)庫的約束關(guān)系有緊密的聯(lián)系(對NHibernat

2、e的了解不多,如果有不妥之處,希望能留下你們的臭雞蛋,等著下回用)。iBatis為我們提供了一種更為靈活的方便的可控的方式去實現(xiàn)類ORM的解決方案。我們需要自己來控制SQL語句,這樣做有好處在于,我們可以更靈活地根據(jù)我們的需求,編寫更加具備性能,功能優(yōu)勢的SQL語句,但它的缺點同樣明顯,我們還是需要管理和編寫SQL語句。但是值得感到高興的是,我們只需要提供這些SQL語句,和為它提供它所需的參數(shù)外,接下來的事情就無需我們參與了。這也是iBatis最核心的功能,也是它為我們所做最多的工作了。根據(jù)配置好的SQL語句和參數(shù)條件,它會動態(tài)生成一條可執(zhí)行的SQL語句,然后根據(jù)具體傳進來的參數(shù)值,為這些SQ

3、L參數(shù)提供不同的具體值。然后根據(jù)配置好的數(shù)據(jù)訪問驅(qū)動,自動為DbCommand添加DbParameter,自動執(zhí)行SQL語句,使用IDataReader返回出數(shù)據(jù)集,生成并返回一個或多個強類型數(shù)據(jù)類對象(數(shù)據(jù)集用IList集合對象表示)。我曾經(jīng)在Community Server中也見過類似的返回強類型數(shù)據(jù)對象的實現(xiàn),但是需要很多的代碼,與直接返回DataTable相比,重復(fù)代碼會更多。所有的這些在iBatis中,只需要提供一個配置文件,調(diào)用它提供的SqlMapper實例對象中的方法就可以很簡單容易地實現(xiàn)了。當然你也許會說,那這樣如果系統(tǒng)比較大的話,可能就需要很多的配置文件了。是的,又陷了另一個

4、極端了。怎么辦呢?沒辦法,魚和熊掌不能兼得啊。這里還不得不重點強調(diào)一下,如果你是經(jīng)常在存儲過程中拼接SQL語句的話,那我就更加推薦你馬上就開始使用iBatis吧。提到數(shù)據(jù)操作,就不能不提到數(shù)據(jù)的安全性和完整性問題了,也就是數(shù)據(jù)操作的事務(wù)問題。如果你是直接使用A進行事務(wù)操作的話,那您可能需要寫更多的代碼了,當然我們可以使用Enterprise Library來簡化我們的工作。那現(xiàn)在通過一段簡單的代碼也看一下在iBatis中該如何實現(xiàn)事務(wù)吧:using ( IDalSession session = sqlMap.BeginTransaction() ) Item item = (Item) sq

5、lMap.QueryForObject(getItem, itemId); item.Description = newDescription; sqlMap.Update(updateItem, item); session.Complete(); / Commit就這么簡單的代碼,它就會幫我們自動管理事務(wù)了。這期間如果出現(xiàn)異常,我們?nèi)匀豢梢圆东@到異常信息。OK,通過上面的介紹,我們已經(jīng)能夠了解到一個大概了。總結(jié)一下,它幫我們自動管理和執(zhí)行SQL語句,并且返回強類型的數(shù)據(jù)對象。從上面的一段簡單的代碼中,你可能已經(jīng)感覺到了它的使用有多么的簡單!并且如果需要的還能夠返回生成的DbCommand,

6、支持我們通過它返回DataTable或者其它的Ado操作返回。但是,這時你會馬上產(chǎn)生另一個疑慮了,我們的工作還是很多啊,比如,編寫數(shù)據(jù)類和配置文件可能工作量并不亞于直接使用A返回DataTable所寫的代碼,并且會更加的沒有技術(shù)含量。所以,對于這些的代碼,我們盡量能通過一些代碼生成工具(我是使用CodeSmith)自動生成大部分,然后再根據(jù)我們需要進行修改。再來看看執(zhí)行效率吧,盡管iBatis或多或少用到反射技術(shù),但由于使用配置文件的形式,性能影響已經(jīng)降到最低了。我曾經(jīng)做過一個測試,用它添加多條記錄和使用UpdateDataSet成批提交數(shù)據(jù)(相同的數(shù)據(jù))的方式進行過比較,總體時間效率不會更差

7、,反而會更快一點。最后不得不再提一點,它的緩存機制做得很好,相同的SQL語句,可以根據(jù)不同的條件值,緩存用這個條件執(zhí)行查詢時的輸出數(shù)據(jù)。它的緩存過期策略是封閉的。詳細細節(jié),相信隨著深入會有所涉及。對它的介紹就先告一段落了,下一篇將會首先介紹一下它的配置工作環(huán)境,重點在于介紹如何使用log4net記錄日志。iBatisnet系列(二) 配置運行環(huán)境和日志處理剛爬完鼓山回來,想到這篇剛剛開始,不敢怠慢,洗完澡休息一下就到電腦旁邊來了?,F(xiàn)在我開始介紹一下iBatis的配置和日志處理吧。iBatis基本的運行環(huán)境配置主要由兩個文件組成,分別是SqlMap.config和Provider.config。

8、它們是必需的兩個配置文件,基中SqlMap.config的功能類似于web.config或者app.config,是iBatis核心的配置文件,它的存放路徑也跟應(yīng)用程序配置文件一樣,必須放在應(yīng)用程序的運行目錄下并且它的文件名是保留的,不可改變的。而Provider.config是一個數(shù)據(jù)驅(qū)動提供類的配置,它的文件名是可以隨意改變的,因為通過SqlMap.config的一個配置節(jié)可以配置它的引用。SqlMap.config包括以下一些主要的配置節(jié),根據(jù)需要,有的配置節(jié)并不是必須的:1. properties :可以根據(jù)需要配置一些常量屬性。如果這些屬性有很多的話可以單獨寫一個文件里面,再通過re

9、source(或url, embedded分別是引用url和編譯在程序中的資源文件)屬性引用進來。如: 這個配置節(jié)是可選的。2. settings:包括有三個配置段: useStatementNamespaces:在文檔中說明它的作用是配置在使用語句ID的時候要不要加命名空間,例中$useStatementNamespaces就是使用properties中的一個屬性,默認是false。cacheModelsEnabled 是配置要不要啟用iBatis的緩存模型,默認是true。validateSqlMap 是配置要不要啟示驗證映射文件,默認是false。 3. providers :配置數(shù)據(jù)驅(qū)

10、動提供類配置文件的路徑和文件名。 4. database : 數(shù)據(jù)庫的信息,包括使用哪些數(shù)據(jù)庫驅(qū)動和數(shù)據(jù)連接字符串的配置。 5. alias : 類型別名的配置,為了使用更方便的使用類(類名更短),就需在這里進行別名的配置。 6. typeHandlers :這個就相對比較復(fù)雜些了,到目前我也沒有使用到。從字面上理解,它是一個類型的處理器,它的作用是當你使用的數(shù)據(jù)庫當中有iBatis不支持或不認識的字段(或者不希望默認的處理方式),那就可以為它取一個名字,并且指定對應(yīng)的.NET類型來處理它。 7. sqlMaps :用來包含當前已經(jīng)寫好的,并且需要用到的數(shù)據(jù)類映射文件。 !- - !- Rem

11、 : If used as embbeded Resources, use -以上就是Sqlmap.config的基本內(nèi)容了。注意,以上凡是涉及到引用外部文件的都支持resouce,url,embedded 三種方式。Provider.config的配置類很簡單,在默認的Provider.config中已經(jīng)有很多不同數(shù)據(jù)庫的數(shù)據(jù)驅(qū)動,而在SqlMapp.config的database配置的provider屬性就是使用Provider.config中已有的不同驅(qū)動中的一個。以下是添加一個A 2.0 數(shù)據(jù)訪問驅(qū)動:OK,以上就是SqlMap.config和Provider.config的基本內(nèi)容。

12、下面我來介紹一下如果利用log4net來記錄iBatisnet的一些運行日志記錄。這也是我當初花了很多的時間才解決的一個問題,因為記錄這些日志太重要了,它可以記錄下每次生成并執(zhí)行的SQL語句,對我們排除配置錯誤有非常重大的意義。而如果你是使用最新版的(當前是1.3.0),但是文檔使用的是1.2.1的話,那可能你怎么折騰都無法搞出結(jié)果來。按照1.2.1的文檔介紹那樣在web.config(app.config) 加上合適的配置節(jié)后,然后把log4net.dll和IBatisNet.Common.Logging.Log4Net.dll拷到bin目錄下后,你可能會認為跟文檔介紹的一樣,生成一個log

13、.txt,并記錄下日志。但事實不是這樣的,在1.3.0的版本中還需要再加上一個配置節(jié)組: 配置組的配置值如下: !- - 經(jīng)過以上的配置后,再運行程序,就會創(chuàng)建log.txt并且記錄日志了。注意:即使是按以上的配置后,有可能還是無法記錄日志,那就可能是log4net.dll和IBatisNet.Common.Logging.Log4Net.dll的中的一個或兩個沒有拷到bin目錄,正常情況下,我們不需引用這兩個程序集,只需把它們拷到運行目錄下,即使你需要記錄日志,但找不到他們,程序仍然能正常執(zhí)行而不會拋出異常,如果你沒有經(jīng)驗的話,解決這個問題可能需要你很多的時間。以上就是今天要介紹的內(nèi)容了,H

14、ope this helps。附注:1 參考資料:Data Mapper Guide-1.2.1.chm ;DataMapper-1.2.1.chm2 配置文件智能提示:把provider.xsd SqlMap.xsd SqlMapConfig.xsd 三個文件拷貝到VS 2005 :C:Program FilesMicrosoft Visual Studio 8XmlSchemas (安裝目錄)VS 2003 :C:Program FilesMicrosoft Visual Studio .NET 2003Common7Packagesschemasxml (安裝目錄)下,就可以在VS ID

15、E下編寫配置文件時得到Intellisense的幫助,前提是配置的文件的第一個節(jié)點寫正確的命名空間和XSD文件。3 HYPERLINK http:/ DEMO HYPERLINK http:/ 下載。使用VS 2005 ,你可能需要安裝有免費版本的SQL 2005。-iBatis.Net系列(三) 映射文件基礎(chǔ)iBatis的核心就在于映射文件(Data Map XML File)。在映射文件里可以定義包括要執(zhí)行各種SQL語句,存儲過程,輸入?yún)?shù)映射,返回結(jié)果映射,緩存機制,并且能通過幾種相對比較復(fù)雜的配置實現(xiàn)對象之間的關(guān)聯(lián)關(guān)系和延遲加載。這也是iBatis區(qū)別ORM框架的,具備更靈活性,更高性

16、能的關(guān)鍵所在。配置文件可以寫得很簡單,也可以很復(fù)雜。復(fù)雜配置文件也是出于更好的設(shè)計,更好性能,更好擴展性方面的目的。再復(fù)雜的配置文件也是有限的,一個映射文件包括:Mapped Statements、Parameter Maps、Result Maps、Cache Models幾個主要的配置,還包括命名空間的配置,類型別名(前一篇中有介紹)的配置。1Mapped Statements :顧名思義就是映射的語句聲明。它是整個iBatis配置核心的核心,真正將被執(zhí)行的SQL語句(或存儲過程)都是必須在這里被顯式聲明。在Mapped Statements里可以包含有:statement、select、

17、insert、update、delete、procedure這6種不同的語句類型。從詞面理解相信就可以了解到這些類型功能的一大半了。statement可以包含所有類型的SQL語句(存儲過程),它是一個泛泛的語句配置,沒特別明確的職責,相反,其它5種類型的語句配置就是專門負責各種不同的SQL語句。下面這張圖列出了各種類型的語句的不同職責和調(diào)用方法。 2Parameter Maps :參數(shù)映射的配置,它是被用來向一個語句(statement)提供所需參數(shù)的配置。每一個Parameter Maps都有一個自己的ID,在需要的時候需要在statement 的 parameterMap屬性中提供它的ID

18、。但是對一個語句來說,它并不是必須,在iBatis中還支持內(nèi)聯(lián)參數(shù)(Inline Parameter Maps)的形式,我們不需單獨寫一個Parameter Maps配置,只需要向parameterClass提供參數(shù)的類型,可以是元數(shù)據(jù)類型,復(fù)合數(shù)據(jù)類型,IDictionary數(shù)型的弱類型對象(使用key,value的鍵值對)。在內(nèi)部訪問數(shù)據(jù)類型的時候只使用#property#的形式訪問對應(yīng)的屬性值。注意:在任何地方使用到的parameterClass類型如果是一個元數(shù)據(jù)類型(int,string etc),都需要使用#value#的形式的來訪問它的值。3Result Maps :返回結(jié)果的映

19、射關(guān)系配置,就是列與屬性的對應(yīng)關(guān)系。在statement中使用resultMap屬性來指定一個結(jié)果映射。對一個statement來說,resultMap也不是必須的,同樣的,它仍然可以被resultClass給代替,因為如果返回出結(jié)果數(shù)據(jù)集的列名跟數(shù)據(jù)對象的屬性相同的話,它會自動去匹配,但是它不保證所有列都被會被正確映射(當某列名在對象中找不對應(yīng)的屬性名,這列值將不被處理)。而resultMap則不同,如果已經(jīng)在resultMap中定義將要使用到列或?qū)傩栽诮Y(jié)果集或數(shù)據(jù)對象中不存在,將會被認為是錯誤的,將會拋出異常。通過上面的表可以看到insert,update,delete三種語句類型是沒有r

20、esultMap和resultClass,因為原則上來說,它們的操作是沒有必要返回結(jié)果集。注意:如果在一個statement中同時指定了resultMap和resultClass屬性的話,那將會優(yōu)先使用resultMap。同時result Map也是一個實現(xiàn)對象復(fù)雜查詢功能的重要手段,如:result map的繼承(與discriminator配合使用),對象的1.1、1.N關(guān)系查詢。4Cache Model :緩存模型。使用在Cache Model中定義好的緩存機制,只需在查詢語句配置的cacheModel屬性就可以很容易地緩存查詢返回的數(shù)據(jù)集。在iBatis中提供了三種的類型的緩存模式(M

21、emory,LRU,FIFO)算法。三種算法主要在于靜態(tài)過期策略上的不同,而它們都有相同的動態(tài)過期依賴策略,即可以設(shè)置執(zhí)行哪些statement時,緩存過期。注意:iBaits的緩存模型正常情況是非常好用的,但是因為緩存過期策略上的封裝性,它在多個服務(wù)器,負載平衡場景下還是有它的局限性。iBatis.Net系列(五) ParameterMap在用Ado.Net進行數(shù)據(jù)庫訪問操作中,最麻煩的就是準備DbCommand必須為它添加DbParameter,特別是當要傳的參數(shù)特別多的情況下,數(shù)據(jù)訪問層的很多代碼都是花在這里。iBatis的ParameterMap配置就是針對這個問題所提出的一種解決方案

22、,基于xml的配置,把字段名和對象的屬性對應(yīng)起來,通過運行時的一些工作,自動為DbCommand提供它所需的參數(shù)集合。從而避免了我們直接寫很多重復(fù)代碼。 在Employees_ParameterMap.xml配置文件中: SELECT EmployeeID,LastName,FirstName FROM Employees WHERE EmployeeID = #EmployeeID# OR LastName = #LastName#使用的是內(nèi)聯(lián)參數(shù)映射的方式,語句的在執(zhí)行查詢時只需為它提供Employee類型的對象,它就會自動去讀自己需要的EmployeeID,LastName屬性的值,返回

23、查詢結(jié)果。在執(zhí)行時它所執(zhí)行的語句如下:SELECT EmployeeID,LastName,FirstName FROM Employees WHERE EmployeeID = param0 OR LastName = param1所需的參數(shù)的提供方式如下:param0=EmployeeID,12, param1=LastName,8bbb7bfb-c并且,在iBatis中還會指出各個參數(shù)的類型:param0=Int32, System.Int32, param1=String, System.String對于下面這個配置: SELECT EmployeeID,LastName,FirstN

24、ame FROM Employees WHERE EmployeeID = #EmployeeID# OR LastName = #LastName# OR Country = #Country# 它所使用的ParameterMap配置如下: 在每一個Parameter映射元素可以指定每個屬性對應(yīng)的列,它的類型和對應(yīng)的數(shù)據(jù)庫的類型,還可以指定當它為空值時的默認值,具體可以參看官方文檔。但是可以看到,我們期待它能和內(nèi)聯(lián)參數(shù)一樣的使用方法,如上配置的那樣??墒切胁恍心??從程序的執(zhí)行結(jié)果來看,是不可以的。由于之前在配置SQL語句的時候基本都是使用內(nèi)聯(lián)參數(shù)沒有特別注意到這點。在使用Parameter

25、Map的時候是不能用#property#的形式顯示地指定要使用的屬性參數(shù),只能通過“?”,順序替代每一個parameter元素,如下: SELECT EmployeeID,LastName,FirstName FROM Employees WHERE EmployeeID = ? OR LastName = ? OR Country = ? 可以看到,由于沒有明顯地指出EmployeeID對應(yīng)哪個屬性,那如果把上面的parameter元素調(diào)換一下,那么EmployeeID所對應(yīng)的參數(shù)值就發(fā)生變化了。同時,也是這個原因,通過這種方式的參數(shù)映射,就無法重復(fù)利用每個參數(shù)了。如果仔細觀察會發(fā)現(xiàn),既然都

26、指定了column屬性了,那它為什么不會自動去配置呢?其實在這邊column屬性是不起作用的,它只會作用在執(zhí)行存儲過程的時候。也就是說上面的Parameter元素中的column屬性不是必須的。下面是一個存儲過程的例子: InsertEmployee InsertEmployee接受兩個參數(shù)LastName和FirstName。我給它提供的映射參數(shù)如下: 上面這樣的配置的結(jié)果是(其中逗號后面的是值):LastName=LastName,9a8bc059-3, FirstName=FirstName,46887db0-2但是當我把他們的位置調(diào)換了一下。它的結(jié)果如下:LastName= First

27、Name,9a8bc059-3, FirstName=LastName,46887db0-2也就是對儲存過程也是一樣的,參數(shù)映射關(guān)系仍然與parameter元素的順序息息相關(guān)的。Column屬性仍然沒有顯示出它的作用。所以使用ParameterMap還有是有一定的局限性的。但是對存儲過程來說,就必須使用這樣的方式,因為它只支持ParameterMap為它提供參數(shù),而不支持內(nèi)聯(lián)參數(shù)。最后總結(jié)列出幾點ParameterMap需要特別注意的幾個細節(jié):1在配置ParameterMap的時候,如果傳入的參數(shù)對像是元數(shù)據(jù)類型(int,string etc),那么在配置Parameter元素的時候,prop

28、erty的屬性名使用value。通過這種情況主要使用在為存儲指定參數(shù)的情況下。2如果ParameterMap中配置的parameter元素不包含在傳入?yún)?shù)對象中(屬性或IDictionary對象的一個key,value項),將會產(chǎn)生異常,而不管在statement中有沒有用到。3在使用parameterMap的extends屬性時,它將會繼承extends值對應(yīng)的parameterMap配置,并且會繼承它的所有的參數(shù)映射,并且順序是從繼承的那配置為基準開始計算。這個在需要用到extends屬性的時候要特別注意。4.在為存儲過程傳參過程要特別注意,參數(shù)映射與存儲過程的參數(shù)之間的順序?qū)?yīng)要正確。而

29、且必須為提供與存儲過程足夠的參數(shù)(parameter配置足夠多),即使存儲過程的部分參數(shù)已經(jīng)有默認值了。否則將拋出System.ArgumentOutOfRangeException異常。 5正常情況下,應(yīng)該盡量使用內(nèi)聯(lián)參數(shù)。iBatis.Net系列(六) ResultMap自從五一寫了三篇關(guān)于iBatis.Net的post后,一直都沒有更新相關(guān)的文章的。一方面是因為自己的能力有限,不夠自信,那三篇連發(fā)表在首頁的信心都沒有。另一方面是因為最近確實很忙,工作上的事情就可以讓我忙得暈頭轉(zhuǎn)向的,實在沒有時間抽空來寫B(tài)log了。但想想,忙只是一個借口,看到 HYPERLINK http:/ Dflyi

30、ng Chen在這兩個月在CnBlogs所取得的成就就讓我慚愧不已,本身自己水平就不能與人家相提并論,卻總是拿“忙”來擋箭牌,實在是不該啊。 酒話過后,進入本次的主題,我們將來討論一下在iBatis中非常重要的一個內(nèi)容,在我個人看來,能否真正用好iBatis的一個關(guān)鍵,這就是ResultMap。字面上理解,它就是結(jié)果集的映射,就是將返回的記錄逐個字段的映射賦值給對象的屬性上。其實如果沒有特殊需求的話我們完全可以使用ResultClass來代替它,因為如果字段與屬性一模一樣的話,查詢出來數(shù)據(jù)集會自動匹配到ResultClass指定的類的實例對象,如果字段名不在屬性中的話,那這個字段將不會被返回的

31、實例體類對象接受,相當于沒有查詢出這個字段一樣的。每個ResultMap都有一個自己的ID,如果你在sqlmap.config中沒有配置使用命名空間的話,那么這個ResulteMap ID是全局(這點在所有的iBatis配置元素都是一樣的),ResultMap一個重要的屬性的是class,它將決定這個ResultMap對應(yīng)的實例的類,換句話講,它的作用是指出結(jié)果集要映射的數(shù)據(jù)類型。在extends屬性中可以設(shè)置它將要繼承的ResultMap,如果給他指定的了值,那么它將會從super Resultmap繼承所的映射配置字段。定義如下: 如果你有正確配置了iBatis的XSD架構(gòu)文件的話,那么這

32、時候就會提示resultMap的定義是不完全的。沒錯,接下來就是要定義Result元素。每一個result元素都是定義一個字段與數(shù)據(jù)類屬性對應(yīng)的映射。在每一個result元素有比較多的屬性參數(shù),其中property和column是必須的,其它的參數(shù)屬性都是可選的。所以我們在每一個resultMap中必須定義超過一個以上的result定義。通常以下的配置就可以完成基本的配置了。 但如果你需要更多的要求的話,result map仍然能夠最大限度的滿足你。columnIndex屬性提供了我們將數(shù)據(jù)集的第幾個下標字段映射到指定的數(shù)據(jù)對象屬性的方案,但是這種方式應(yīng)該盡量的少用,你會發(fā)現(xiàn)這對我們以后的維護

33、和可讀性會產(chǎn)生很大的副作用。dbType屬性明確指出這個字段對應(yīng)的數(shù)據(jù)庫的類型,大多數(shù)情況我很少會用到。type屬性則明確指出這個字段將對應(yīng)的數(shù)據(jù)對象屬性的數(shù)據(jù)類型,通常如果你想保證類型安全的話,設(shè)置這個屬性是很必要的。resultMapping屬性則稍微復(fù)雜一些,它是用在一種場景下,如果一個數(shù)據(jù)類的屬性本身不是基元數(shù)據(jù)類型,而是一個復(fù)雜數(shù)據(jù)類型的話,那我們就不可能很簡單地給它一個簡單的result元素就了事了,還必須給他一個完整的resultMap。而resultMapping屬性就是為了完成這個功能而存在的。它的屬性值是一個已存在的resultMap的ID。nullValue屬性就沒什么好

34、講的了,它是給出當這個字段的值為null的時候,它的默認值是多少。select屬性同resultMapping一樣比較復(fù)雜一樣,先說一下它的屬性值必須是一個返回數(shù)據(jù)集合的查詢語句的ID,能配置這個屬性的數(shù)據(jù)類屬性可以是一個基元類型,復(fù)合類型,也可以是一個包括多條數(shù)據(jù)的集合類型,這些類型都行,沒有問題的。它的一處重要的存在意義就在于描述不同表之間的關(guān)系問題,通過本次的查詢,你想不通過join的手段從另一個表查詢相關(guān)字段的時候,你就可以使用select屬性。如下: SELECT * FROM Children WHERE ParentID = #id# 這樣就可以做到不用通過編程的方式來表示不同表

35、的關(guān)聯(lián)關(guān)系和數(shù)據(jù)讀取問題。但是這樣有可能存在一種問題,如果你每次都要讀取數(shù)據(jù)的時候,你會發(fā)現(xiàn)你會產(chǎn)生更多次的與數(shù)據(jù)庫交互的情況,并且即使你不是每次都需要這數(shù)據(jù),那會不會造成數(shù)據(jù)讀取的浪費呢?接下來的lazyLoad屬性就為我們提供了第二種問題的解決方案了,那就是數(shù)據(jù)的延遲加載,沒錯,延遲加載可以大大改善數(shù)據(jù)訪問的性能,它只是要需的時候才去讀取這些數(shù)據(jù),對于主從表關(guān)系的時候,這樣的方式可能是最好的解決方式了。 OK,關(guān)于ResultMap的介紹就先到此為止,接下來我要記錄一下,我在使用過程中遇到的一些問題: 一在使用ResultMap的時候,你要特別注意,如果你在ResultMap中給出的配置字

36、段,但是你返回的數(shù)據(jù)集的時候卻沒有返回這個字段,那程序?qū)⒊鰭伋霎惓?。但是相反的,如果你返回了一些字段,卻沒有在ResultMap給出配置定義的話,那么那些字段將不會被處理而不會給你任何的提示,相當沒有查詢出這些字段。你要特別注意這個問題。 二如果沒有特別需求的情況,我建議還是把數(shù)據(jù)類的屬性設(shè)計成與數(shù)據(jù)庫字段字一樣的比較,這樣如果一般情況下我們都可以不用寫這個ResultMap,事實上如果沒有這樣的特殊要求,那么去寫這個ResultMap仍然是一件非常耗時,并且容易出錯的一份差事。 三在使用lazyLoad的時候要特別注意,不是什么類型的數(shù)據(jù)都可以lazyLoad的,只有是實現(xiàn)的IList的接口

37、的類型,并且數(shù)據(jù)類的屬性定義為IList類型的字段才能被lazyLoad。(關(guān)于是否只有IList類型的屬性才能被lazyLoad的問題還需要探討一下,因為就我使用的經(jīng)驗只有這種類型才可以,甚至是Generic版的IList都不支持)。而且你在使用它的時候,還不能把這個IList類型的屬性轉(zhuǎn)換成你真正的數(shù)據(jù)類型。因為在運行時,這個屬性會被包裝成一個動態(tài)的類型,這個動態(tài)類型仍然實現(xiàn)了IList接口,就是因為這個動態(tài)類型才擴展了我們可以lazyLoad的功能。這時候在程序中使用的是運行時的動態(tài)類型所以你沒辦法進行強類型轉(zhuǎn)換。 問題暫時沒有想到更多了,如果以后還有關(guān)于resultMap的問題,我都會

38、更新上來,也希望大家一起來指正我的一些錯誤和不足,一起完善。不要讓我的一些錯誤的實踐誤導(dǎo)了初學(xué)者,謝謝 HYPERLINK http:/ ibatis使用存儲過程傳遞參數(shù)SQL Map通過元素支持存儲過程。下面的例子說明如何使用具有輸出參數(shù)的存儲過程。 call swap_email_address (?, ?) 調(diào)用上面的存儲過程將同時互換兩個字段(數(shù)據(jù)庫表)和參數(shù)對象(Map)中的兩個email http:/ Clinton Begin 著 劉濤() 譯 開發(fā)指南 iBATIS SQL Maps Page 21 of 62 地址。如果參數(shù)的mode屬性設(shè)為INOUT或OUT,則參數(shù)對象的值

39、被修改。否則保持不變。 注意!要確保始終只使用JDBC標準的存儲過程語法。參考JDBC的CallableStatement文檔以獲得更詳細的信息。 -IBatisNet基礎(chǔ)組件 DomSqlMapBuilder,其作用是根據(jù)配置文件創(chuàng)建SqlMap實例??梢酝ㄟ^這個組件從Stream, Uri, FileInfo, or XmlDocument instance 來讀取sqlMap.config文件。SqlMap是IBatisnet的核心組件,提供數(shù)據(jù)庫操作的基礎(chǔ)平臺。SqlMap可通過DomSqlMapBuilder創(chuàng)建。 Assembly assembly = Assembly.Load(

40、IBatisNetDemo); Stream stream = assembly.GetManifestResourceStream(IBatisNetDemo.sqlmap.config); DomSqlMapBuilder builder = new DomSqlMapBuilder(); sqlMap = builder.Configure( stream ); SqlMap是線程安全的,也就是說,在一個應(yīng)用中,可以共享一個SqlMap實例。 SqlMap提供了眾多數(shù)據(jù)操作方法,下面是一些常用方法的示例,具體說明文檔參見 ibatis net doc,或者ibatisnet的官方開發(fā)手冊

41、。SqlMap基本操作示例例1:數(shù)據(jù)寫入操作(insert、update、delete)SqlMap.BeginTransaction();Person person = new Person();Person.FirstName = “Zhang”;Person.LastName = “shanyou”;int Id = (int) SqlMap.Insert(InsertPerson, person);SqlMap.CommitTransaction();.例2:數(shù)據(jù)查詢:Int Id = 1;Person person = SqlMap.QueryForObject(, Id);retu

42、rn person;例3:在指定對象中存放查詢結(jié)果:Int Id = 1;Person person = new Person();person = SqlMap.QueryForObject(GetBirthday, Id, person);return person;例4:執(zhí)行批量查詢(Select)IList list = null;list = SqlMap.QueryForList(SelectAllPerson, null);return list;例5:查詢指定范圍內(nèi)的數(shù)據(jù)(Select)IList list = null;list = SqlMap.QueryForList(S

43、electAllPerson, null, 0, 40);return list;例6:結(jié)合RowDelegate進行查詢:public void RowHandler(object obj, IList list)Product product = (Product) object;product.Quantity = 10000;SqlMapper.RowDelegate handler = new SqlMapper.RowDelegate(this.RowHandler);IList list = sqlMap.QueryWithRowDelegate(getProductList,

44、null, handler);例7:分頁查詢(Select)PaginatedList list = sqlMap.QueryForPaginatedList (“getProductList”, null, 10);list.NextPage();list.PreviousPage();例8:基于Map的批量查詢(select)IDictionary map = sqlMap.QueryForMap (“getProductList”, null, “productCode”);Product p = (Product) map“EST-93”;OR映射相對于Nhibernate等ORM實現(xiàn)

45、來說,IBatisnet的映射配置更為直接,下面是一個典型的配置文件:!模塊配置 !statement配置 select PER_ID, PER_FIRST_NAME, PER_LAST_NAME, PER_BIRTH_DATE, PER_WEIGHT_KG, PER_HEIGHT_M from PERSON select PER_ID, PER_FIRST_NAME, PER_LAST_NAME, PER_BIRTH_DATE, PER_WEIGHT_KG, PER_HEIGHT_M from PERSON where PER_ID = #value# $selectKey insert i

46、nto Person ( PER_FIRST_NAME, PER_LAST_NAME, PER_BIRTH_DATE, PER_WEIGHT_KG, PER_HEIGHT_M) values (#FirstName#,#LastName#,#BirthDate#, #WeightInKilograms#, #HeightInMeters#) delete from Person where PER_ID = #Id# 可以看到,映射文件主要分為兩個部分:模塊配置和Statement配置。模塊配置包括:1、typeAlias節(jié)點定義了本映射文件中的別名,以避免過長變量值的反復(fù)書寫,此例中通過ty

47、peAlias節(jié)點為類“IBatisNetDemo.Domain.Person”定義了一個別名“Person”,這樣在本配置文件中的其他部分,需要引用“IBatisNetDemo.Domain.Person”類時,只需以其別名替代即可。2、cacheModel節(jié)點定義了本映射文件中使用的Cache機制: 這里聲明了一個名為“person-cache”的cacheModel,之后可以在Statement聲明中對其進行引用: select PER_ID, PER_FIRST_NAME, PER_LAST_NAME, PER_BIRTH_DATE, PER_WEIGHT_KG, PER_HEIGHT

48、_M from PERSON 這表明對通過id為SelAllPerson的“Select Statement”獲取的數(shù)據(jù),使用CacheModel “person-cache”進行緩存。之后如果程序再次用此Satement進行數(shù)據(jù)查詢。即直接從緩存中讀取數(shù)據(jù),而不需再去數(shù)據(jù)庫查詢。CacheModel主要有幾個配置點:參數(shù)描述flushInterval設(shè)定緩存有效期,如果超過此設(shè)定值,則將此CacheModel緩存清空CacheSize本Cachemodel中最大的數(shù)據(jù)對象數(shù)量flushOnExecute指定執(zhí)行特定的Statement時,將緩存清空。如UpdatePerson操作將更新數(shù)據(jù)庫

49、中用戶信息,這將導(dǎo)致緩存中的數(shù)據(jù)對象與數(shù)據(jù)庫中的實際數(shù)據(jù)發(fā)生偏差,因此必須將緩存清空以避免臟數(shù)據(jù)的出現(xiàn)。3、resultMaps節(jié)點resultMaps實現(xiàn)dotnet實體到數(shù)據(jù)庫字段的映射配置: Statement配置:Statement配置包含了數(shù)個與Sql Statement相關(guān)的節(jié)點,元素是一個通用的能夠包容任意類型sql的元素。我們可以用更多細節(jié)的元素。這些細節(jié)元素提供更好的錯誤檢查以及一些更多的功能。(例如,一個插入函數(shù)能夠返回數(shù)據(jù)庫自動生成的key)。以下表格總結(jié)了聲明類型元素以及他們的特性和屬性。Statement ElementAttributesChild Elements

50、Methodsid parameterClass resultClass parameterMap resultMap cacheModel xmlResultName (Java only)All dynamic elementsinsert update delete All query methodsid parameterClass parameterMapAll dynamic elements (.NET only)insert update delete id parameterClass parameterMapAll dynamic elements (.NET only)i

51、nsert update deleteid parameterClass parameterMapAll dynamic elements (.NET only)insert update deleteid parameterClass resultClass parameterMap resultMap cacheModelAll dynamic elements (.NET only)All query methodsid parameterClass resultClass parameterMap resultMap xmlResultName (Java only)All dynam

52、ic elements insert update delete All query methods其中,statement最為通用,它可以代替其余的所有節(jié)點。除statement之外的節(jié)點對應(yīng)于SQL中的同名操作(procedure對應(yīng)存儲過程)。使用Statement定義所有操作,缺乏直觀性,建議在開發(fā)中根據(jù)操作目的,各自選用對應(yīng)的節(jié)點名加以說明。一方面,使得配置文件更加直觀,另一方面,也可以借助xsd對i節(jié)點聲明進行更有針對性的檢查,以避免配置上的失誤。 select * from PRODUCT where PRD_ID = ?|#propertyName# order by $sim

53、pleDynamic$其中“ ”包圍的部分為可能出現(xiàn)的配置項,各參數(shù)說明見下表。具體的使用方法參見IBatisNet官方文檔。參數(shù)描述parameterMap參數(shù)映射,需結(jié)合parameterMap節(jié)點對映射關(guān)系加以定義,對于存儲過程之外的statement而言,建議使用parameterClass作為參數(shù)配置方式,一方面避免了參數(shù)映射配置工作,另一方面其性能表現(xiàn)更加出色parameterClass參數(shù)類。指定了參數(shù)類型的完整類名(包括命名空間),可以通過別名避免每次書寫冗長的類名resultMap結(jié)果映射,需結(jié)合resultMap節(jié)點對映射關(guān)系加以定義resultClass結(jié)果類。指定了結(jié)果

54、類型的完整類名(包括命名空間),可以通過別名避免每次書寫冗長的類名cacheModelStatement對應(yīng)的Cache模塊一般而言,對于insert、update、delete、select語句,優(yōu)先采用parameterClass和resultClass.。paremeterMap使用較少,而ResultMap則大多用于存儲過程處理和查詢。存儲過程相對而言比較封閉(很多情況下需要調(diào)用現(xiàn)有的存儲過程),其參數(shù)名和返回的數(shù)據(jù)字段命名往往不符合dotnet編程的命名規(guī)范)。使用resultMap建立字段名同Dotnet對象的屬性之間的映射關(guān)系就非常有效。另一方面,由于通過ResultMap指定了

55、字段名和字段類型,ibatisnet無需再通過來動態(tài)獲取字段信息,在一定程度上也提升了性能。下面特別說明一下ibatisnet對Stored Procedures的處理,iBatis數(shù)據(jù)映射把存儲過程當成另外一種聲明元素。示例演示了一個基于存儲過程的簡單數(shù)據(jù)映射。ps_swap_email_address. prc_InsertCategory. prc_InsertAccount. 示例是調(diào)用存儲過程swapEmailAddress的時候?qū)跀?shù)據(jù)庫表的列和兩個email地址之間交換數(shù)據(jù),參數(shù)對象亦同。參數(shù)對象僅在屬性被設(shè)置成INOUT或者OUT的時候才會被修改。否則,他們將不會被修改。當然

56、,不可變得參數(shù)對象是不會被修改的,比如string.Net中,parameterMap屬性是必須的。DBType,參數(shù)方向,大小由框架自動發(fā)現(xiàn)的。(使用CommandBuilder實現(xiàn)的) HYPERLINK http:/ IBatisNet配置 結(jié)合上面示例中的IbatisNet配置文件,下面對配置文件中各節(jié)點的說明: !- Rem : If used via a DataAccess context, properties tag will be ignored - 1. properties節(jié)點可以根據(jù)需要配置一些常量屬性。如果這些屬性有很多的話可以單獨寫一個文件里面,再通過resour

57、ce(或url, embedded分別是引用url和編譯在程序中的資源文件)屬性引用進來properties 節(jié)點參數(shù)參數(shù)描述resource指定the properties文件從application的根目錄進行加載resource=properties.configurl指定the properties文件從文件的絕對路徑進行加載url=c:WebMyAppResourcesproperties.config-or-url=file:/c:WebMyAppResourcesproperties.configembedded指定文件可以作為程序集的資源文件進行加載embedded= data

58、base.config, IBatisNetDemo”上面例子中Properties文件的配置如下: 下面解釋一下這個文件的節(jié)點參數(shù)Property節(jié)點參數(shù)參數(shù)描述key定義key (variable) 名字key=usernamevalue定義DataMapper 中使用的 key的值value=mydbuser2. setting節(jié)點Setting節(jié)點參數(shù)參數(shù)描述cacheModelsEnabled 是否啟用sqlMap上的緩存機制Example: cacheModelsEnabled=”true”Default: true (enabled)useStatementNamespaces 是否使用Satement命名空間,這里的命名空間指的是映射文件中sqlMap節(jié)點的namespace屬性,如上例中針對Person表的映射文件sqlMap節(jié)點 這里,指定了此sqlM

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論