NHibernate是一款面向.NET環(huán)境的對(duì)象/關(guān)系數(shù)據(jù)庫(kù)映射工具。提供了將域模型(類)映射到傳統(tǒng)關(guān)系數(shù)據(jù)庫(kù)并生成查詢所需的框架。它的目標(biāo)主要是用于與數(shù)據(jù)持久化相關(guān)的編程任務(wù),大幅度減少開(kāi)發(fā)時(shí)人工使用SQL和ADO.NET處理數(shù)據(jù)的時(shí)間。能夠使開(kāi)發(fā)人員從原來(lái)枯燥的SQL語(yǔ)句的編寫(xiě)中解放出來(lái),解放出來(lái)的精力可以讓開(kāi)發(fā)人員投入到業(yè)務(wù)邏輯的實(shí)現(xiàn)上。
相關(guān)配置
一、基本配置
1、需要一個(gè)自定義的配置節(jié)點(diǎn),一般放在Web.config里或App.config里面,當(dāng)然你可以自己定義實(shí)際位置
(1)、聲明自定義配置節(jié)點(diǎn)
name:自定義配置節(jié)點(diǎn)名稱。
type:處理程序位置。
(2)、聲明是哪一個(gè)數(shù)據(jù)庫(kù)驅(qū)動(dòng)程序。
(3)、數(shù)據(jù)庫(kù)連接。
(4)、所使用的SQL方言,通過(guò)這個(gè)方言,才知道要將你寫(xiě)的查詢語(yǔ)句,翻譯成何種數(shù)據(jù)庫(kù)的SQL語(yǔ)句。
(5)、設(shè)定映射文件默認(rèn)所在的程序集。
2、軟件的映射文件一定要設(shè)為嵌入的資源。
3、軟件的實(shí)體類所有的屬性都要加上virtual-虛屬性,作為一個(gè)ORM框架,它需要知道如何將數(shù)據(jù)庫(kù)的表與對(duì)應(yīng)的實(shí)體類相關(guān)聯(lián),通過(guò)映射文件的方式來(lái)獲得這方面的信息。
二、獲取映射文件相關(guān)配置
軟件中的映射文件以hbm.xml為后綴結(jié)束,獲取映射文件的方法有3種方法:
1、從config程序配置文件獲取映射文件位置
運(yùn)行在.Net程序上,需要自己提供一個(gè)自定義配置節(jié)點(diǎn),這個(gè)配置節(jié)點(diǎn)里面包含了數(shù)據(jù)庫(kù)連接,什么數(shù)據(jù)庫(kù)等等信息。其中就包括了配置文件所在位置的信息。
會(huì)直接從Web.config或App.config文件上的配置節(jié)點(diǎn)上讀取這個(gè)節(jié)點(diǎn),然后從節(jié)點(diǎn)指定的程序集去查找映射文件。
2、編程的方式,寫(xiě)在代碼里
(1)、AddFile 指定映射文件
ISessionFactory sessionFactory = new Configuration().Configure().AddFile(@"C:UsersAdministratorDesktopNHibernate學(xué)習(xí)ModelMappingPerson.hbm.xml").BuildSessionFactory();
ps:當(dāng)你不寫(xiě)全路徑的時(shí)候,也就是只寫(xiě)個(gè)文件名,那么它就會(huì)從配置文件讀取程序集,到配置文件中指定的程序集去加載此映射文件。如果配置文件并不指定程序集,那么就從當(dāng)前程序集中查找指定名的映射文件。但這種方式,不必設(shè)置嵌入的資源,但要記得設(shè)置為始終復(fù)制。
Configuration cfg = new Configuration().AddFile("Mapping/Person.hbm.xml");ISessionFactory sessionFactory = cfg.BuildSessionFactory();
這種方法只是指定一個(gè)文件,但是可以鏈?zhǔn)街付ǘ鄠€(gè)如:AddFile("f1").AddFile("f2")。
(2)、AddAssembly
還有另外一種方法,在創(chuàng)建Configuration時(shí)指定程序集。
Configuration cfg = new Configuration().AddAssembly("Model"); //Model為映射文件所在程序集名稱
ISessionFactory sessionFactory = cfg.BuildSessionFactory();
這種方法,即使.config配置文件里
節(jié)點(diǎn)為空也沒(méi)關(guān)系,軟件會(huì)自動(dòng)到指定的程序集里查找所有以.hbm.xml結(jié)尾的文件。
(3)、AddClass
這種方式,可以消除程序?qū)ξ募窂阶址挠簿幋a。
Configuration cfg = new Configuration().AddClass(typeof(Model.Person));
ISessionFactory sessionFactory = cfg.BuildSessionFactory();
但是缺點(diǎn)也非常明顯,類名必須與映射文件的名稱相同。不然,編譯就無(wú)法通過(guò),因?yàn)镻erson類都找不到。另外,映射文件Person.hbm.xml必須放在根目錄。會(huì)自動(dòng)到程序中去查找名為Person.hbm.xml文件。使用方法
步驟一、創(chuàng)建數(shù)據(jù)庫(kù)和映射的表
步驟二、創(chuàng)建項(xiàng)目和實(shí)體類映射類以及類對(duì)應(yīng)的映射文件
新建一個(gè)網(wǎng)站,網(wǎng)站創(chuàng)建之后,網(wǎng)站解決方案右鍵,選擇添加 => 新建項(xiàng)目 => 類庫(kù)
給類庫(kù)起名
與之前寫(xiě)的實(shí)體類不同的是此實(shí)體類每個(gè)屬性前面就加了virtual,虛方法或者屬性的關(guān)鍵字,子類可以從新定義(override),在這里必須有virtual 關(guān)鍵字,不然程序運(yùn)行就會(huì)出錯(cuò)。筆者判斷此原因可能是程序在運(yùn)行時(shí)候此屬性被重新映射(定義),所以必須添加virtual關(guān)鍵字。
然后比較重要的一個(gè)步驟就是配置此實(shí)體類對(duì)應(yīng)的映射文件,此映射xml文件名稱固定為“實(shí)體類.hbm.xml”
實(shí)體類的屬性配置,其中“Com.uuu9.nHibernate”為上述所建類庫(kù)(生成程序集的名稱)的名稱。注意:每個(gè)實(shí)體類對(duì)應(yīng)的映射文件“實(shí)體類.hbm.xml”,都要右鍵設(shè)置生成類型屬性為:嵌入的資源
因?yàn)楫?dāng)作為一個(gè)資源被嵌入后,項(xiàng)目的默認(rèn)命名空間與文件名就組成了資源訪問(wèn)的完整名稱,軟件運(yùn)行時(shí)會(huì)訪問(wèn)資源的完整名稱,但如果不設(shè)置,程序就找不到映射文件,就會(huì)認(rèn)為此類沒(méi)有設(shè)置映射,也就不能使用操作。
步驟三、添加項(xiàng)目引用與NHibernate(版本2.1.2)的dll文件
步驟四、配置hibernate.cfg.xml文件(數(shù)據(jù)庫(kù)映射信息配置)
hibernate.cfg.xml文件為NHibernate的配置文件,名稱固定,且必須放到Bin目錄中
name可以自己隨意定義:NHibernate.Dialect.MsSql2005Dialect
“NHibernate.Dialect.MsSql2005Dialect”可根據(jù)實(shí)際的數(shù)據(jù)庫(kù)的需要改為 2000Dialect、2008Dialect。
注意:“”為實(shí)體類生成程序集的名稱,一直要寫(xiě)正確,一定要有。
步驟五、創(chuàng)建和使用NHibernate
至此NHibernate制作完畢。體系結(jié)構(gòu)
1、SessionFactory(NHibernate.IsessionFactory):它是Session的工廠,是ConnectionProvider的客戶??梢猿钟幸粋€(gè)可選的(第二級(jí))數(shù)據(jù)緩存,可以在進(jìn)程級(jí)別或集群級(jí)別保存的可以在事物中重用的數(shù)據(jù)。
2、會(huì)話(NHibernate.ISession):單線程,生命期較短的對(duì)象,代表應(yīng)用程序和持久化層之間的一次對(duì)話。封裝了一個(gè)ADO.NET連接,也是Transaction的工廠。保存有必需的(第一級(jí))持久化對(duì)象的緩存,用于遍歷對(duì)象圖,或者通過(guò)標(biāo)識(shí)符查找對(duì)象。
3、持久化對(duì)象(Persistent)及其集合(Collections):生命期較短的單線程的對(duì)象,包含了持久化狀態(tài)和商業(yè)功能。這些可能是普通的對(duì)象,唯一特別的是現(xiàn)在從屬于且僅從屬于一個(gè)Session。一旦Session被關(guān)閉,它們都將從Session中取消聯(lián)系,可以在任何程序?qū)幼杂墒褂茫ū热?,直接作為傳送到表現(xiàn)層的DTO,數(shù)據(jù)傳輸對(duì)象)。
4、臨時(shí)對(duì)象(Transient Object)及其集合(Collection):目前沒(méi)有從屬于一個(gè)Session的持久化類的實(shí)例。這些可能是剛剛被程序?qū)嵗?,還沒(méi)有來(lái)得及被持久化,或者是被一個(gè)已經(jīng)關(guān)閉的Session實(shí)例化。
5、事務(wù)Transaction (NHibernate.ITransaction):(可選)單線程,生命期較短的對(duì)象,應(yīng)用程序用其來(lái)表示一批工作的原子操作,它是底層的ADO.NET事務(wù)的抽象。一個(gè)Session在某些情況下可能跨越多個(gè)Transaction事務(wù)。
6、ConnectionProvider(NHibernate.Connection.ConnectionProvider):(可選)ADO.NET連接的工廠。從底層的IDbConnection抽象而來(lái)。對(duì)應(yīng)用程序不可見(jiàn),但可以被開(kāi)發(fā)者擴(kuò)展/實(shí)現(xiàn)。
7、TransactionFactory(net.sf.hibernate.TransactionFactory):(可選)事務(wù)實(shí)例的工廠。對(duì)應(yīng)用程序不可見(jiàn),但可以被開(kāi)發(fā)者擴(kuò)展/實(shí)現(xiàn)。常見(jiàn)問(wèn)題
處理字段NULL值的問(wèn)題
因?yàn)?birthday 在數(shù)據(jù)庫(kù)里是“smalldatetime”類型,所以我們?cè)趧?chuàng)建表實(shí)體、以及xml映射的時(shí)候,可能會(huì)把 birthday 的類型設(shè)置為“DateTime”。但是經(jīng)過(guò)這樣的設(shè)置后,可能會(huì)出現(xiàn)以下錯(cuò)誤提示:
SqlDateTime 溢出。必須介于 1/1/1753 12:00:00 AM 和 12/31/9999 11:59:59 PM 之間。
說(shuō)明: 執(zhí)行當(dāng)前 Web 請(qǐng)求期間,出現(xiàn)未處理的異常。請(qǐng)檢查堆棧跟蹤信息,以了解有關(guān)該錯(cuò)誤以及代碼中導(dǎo)致錯(cuò)誤的出處的詳細(xì)信息。 異常詳細(xì)信息: System.Data.SqlTypes.SqlTypeException: SqlDateTime 溢出。必須介于 1/1/1753 12:00:00 AM 和 12/31/9999 11:59:59 PM 之間。
解決方法:
當(dāng)庫(kù)中的字段為 DateTime 類型的時(shí)候,我們?cè)趧?chuàng)建表實(shí)體、以及xml映射的時(shí)候,應(yīng)該將類型設(shè)置為“String”。
0條評(píng)論