|
前言
這篇文章出自于我嘗試學習使用Nhiberbnate的挫敗感。我發(fā)現(xiàn)好像Nhibernate全部的介紹材料不是很模糊就是太詳細。我所需要的就是一個簡單直接的教程,能讓我盡快對NHibernate熟悉起來。我從來沒有找到。幸運的是,這篇文章將會滿足別人的這些需求。
這篇文章有些長,但是我鼓勵你以你的方式來閱讀。NHibernate是一個復雜的程序,是一個綿延曲折的學習過程。這篇文章將為你踏平曲折,從幾天或是幾周縮短到幾個小時。
問題
NHibernate目的是解決一個眾所周知的問題,對象持久代碼在開發(fā)過程中的瓶頸問題。很多文章表明:1/4到1/3的程序代碼是關于對象持久化,從數(shù)據(jù)庫中讀取數(shù)據(jù),和將數(shù)據(jù)寫回數(shù)據(jù)庫。代碼是重復的,耗費時間的,還有很多瑣碎的代碼要寫。
對于這個問題,有很多解決方案是可用的。代碼生成可以在幾秒鐘生成數(shù)據(jù)訪問代碼。但是如果業(yè)務模型改變,這些代碼需要重新生成。"對象關系映射"(ORMs)使用了一種新的方式,像NHibernate。他們管理數(shù)據(jù)訪問更加透明,提供了很多簡潔的API,可以使用一輛行代碼來實現(xiàn)加載和保存整個對象。
介紹NHibernate
NHibernate是一個持久化引擎框架。它從數(shù)據(jù)庫中加載業(yè)務對象,以及將這些對象的變化更新到數(shù)據(jù)庫中。從文章上面可以看出,它可以只使用一兩行代碼實現(xiàn)業(yè)務對象的加載和保存。
NHibernate使用映射文件來引導從數(shù)據(jù)庫數(shù)據(jù)到業(yè)務對象的轉(zhuǎn)換。還有一種方法,你可以使用類的特性和屬性來替代映射文件。為了讓事情盡量簡單,我們在這篇文章中將使用映射文件,而不是使用類特性。另外,映射文件能夠很清晰的將業(yè)務邏輯和持久化代碼分開。
好了,我們只需要在程序中添加幾行代碼,和為每一個映射文件創(chuàng)建持久化類,而且NHibernate可以照顧到所有的數(shù)據(jù)庫操作。真不知道使用NHibernate將為我們節(jié)省多少開發(fā)時間。
記住在.NET環(huán)境下,NHibernate并不是唯一的ORM框架。有許多商業(yè)的和開源的產(chǎn)品可以提供這樣的服務。NHibernate是其中最流行的,主要是因為他遺傳自強大的Hibernate,一個Java環(huán)境下非常流行的ORM框架。另外,微軟也為ADO.NET提供了"Entity Framework",來提供ORM服務。但是,這個產(chǎn)品已經(jīng)延遲,好長時間已經(jīng)沒有再釋放了。
安裝NHibernate
使用NHibernate的第一步就是下載NHibernate和Log4NET(一個開源的日志記錄程序,NHibernate使用它來記錄錯誤和警告),NHibernate包含了Log4NET最新的版本,你也可以下載整個Log4NET安裝包,這里是下載地址:
NHibernate不是直接需要Log4NET,可是在調(diào)試期間它的自動記錄日志功能非常有用。
現(xiàn)在開始
在這篇文章中,我將使用一個簡單的示例程序,而不是解說如何使用NHibernate來進行數(shù)據(jù)訪問。這是一個控制臺應用程序,通過消除UI代碼讓程序變的更加簡單。這個程序?qū)?chuàng)建很多個業(yè)務對象,來使用NHibernate來對他們進行持久化,然后將他們從數(shù)據(jù)庫中讀取出來。
為了程序運行起來,你需要做一下幾個事情:
- 為陳旭添加NHibernate和Log4NET的程序集引用
- 為程序添加數(shù)據(jù)庫
- 修改數(shù)據(jù)庫連接字符串
這個示例程序引用NHibernate和Log4NET。這些應用應該被你的機器識別,如果你的NHibernate和log4NET安裝在默認的目錄里。如果這些引用不被識別,你可以分別使用NHibernate.dll和Log4NET.dll來替換引用位置。這些DLL文件可以在NHibernate的安裝目錄中找到。
這個示例程序是按照SQL Server Express 2005來配置的,數(shù)據(jù)庫文件(NhibernateSimpleDemo.mdf和NhibernateSimpleDemo.ldf)已經(jīng)打包在壓縮文件里。你可以將數(shù)據(jù)庫搭在你機器的SQL Server上。
最后,數(shù)據(jù)庫的連接字符串配置在App.config文件中,默認你使用的是SQL Server數(shù)據(jù)庫。你可以自己根據(jù)自己機器SQL Server的版本,來修改數(shù)據(jù)庫的連接字符串。
業(yè)務模型
這里有兩種方法使用NHibernate創(chuàng)建應用程序。第一種是“以數(shù)據(jù)為中心”的方法,它從數(shù)據(jù)模型和創(chuàng)建業(yè)務對象開始。第二種是“以對象為中心”的方法,從業(yè)務模型和創(chuàng)建數(shù)據(jù)庫來持久化這個模型開始。這個示例程序使用以對象為中心的方式。
這里示例中的業(yè)務模型:
這個模型表現(xiàn)了一個訂單系統(tǒng)的框架,這個模型是不完整的,這里只是使用了幾個類來解說使用NHibernate對象持久化。顯然這個模型的設計不能代表最佳實踐,但是用來展示NHibernate是怎樣工作的已經(jīng)足夠應付了。
此文將使用這個模型來解說使用NHibernate進行對象持久化的幾個概念。
- 處理簡單屬性
- 處理Components
- 處理one-to-many
- 處理many-to-one
- 處理many-to-many
此文不會涉及高級主題,像繼承。
這個模型由5個類組成,其中的4個是要持久化的類,非持久化類OraderSystem當做這個對象模型的宿主。我們將會在程序運行時初始化OrderSystem對象,然后我們將加載其他的對象到OrderSystem中來。
OrderSystem.Customers屬性擁有銷售者的客戶列表,Customers可以通過CustomerID來訪問,每一個Customer對象擁有一個ID,name,和address、一個序列的orders。address將被包成一個單獨的Address類中。
Order類包含了一個訂單的ID,時間,顧客信息,和許多購買的產(chǎn)品信息。
Product類包含ID,名稱。
請注意我們只注重NHibernate是怎么工作的,程序初始化時,Product對象將被實例化放入OrderSystem.Catalog屬性中,當一個訂單被創(chuàng)建時,Product對象引用將不復制到Order.OrderItems屬性中。
NHibernate一個強大的特點就是不需要為業(yè)務類實現(xiàn)特別的接口。事實上,業(yè)務對象通常不會擔心被持久化機制來加載和保存他們。NHibernate使用的映射數(shù)據(jù)保存在分離的XML文件中。
數(shù)據(jù)庫
數(shù)據(jù)庫和對象模型并不是完全匹配,對象模型中包含一個Address類,但是數(shù)據(jù)庫中并沒有與之對應的表。數(shù)據(jù)庫中有OrderItems表,但是對象模型中并沒有與之對應的持久化的類。這里的不匹配并不是故意的,我們想展示的NHibernate其中的一個概念就是這里并不需要數(shù)據(jù)庫中的表跟類是一一對應的。
這里是為什么不完全匹配的原因:
- Address類并不能代表業(yè)務模型的一個實體,相反,它只代表一個實體的值,在這個示例中,代表Customer.Address 屬性,我們將Address分離一個單獨的類,這樣我們可以解說什么叫NHibernate使用“Component mapping”。
- OrderItems表是多對多關系中Orders和Products的連接表,這樣也不能代表對象模型中的一個實體。
Customer表包含了一個普通Customer信息的骨架,包含Customer的Address信息。最佳實踐不會像我們這樣,將會把Address分離在一個單獨的表中。我們把Address信息保存在Customer表中,這樣我們可以解釋什么是NHibernate使用‘Components’類,而不使用Address自己的表,我們將在下面討論Components的詳細用法。
Orders表只包含一個訂單的最簡單的信息,只有ID,時間,和CustomerID。Orders和Customers之間的關系通過一個外鍵orders.ustomerID 列對應 Customer.ID列。
所有的訂單學要一個多對多的關系(每一條訂單包含很多條商品信息,每一條商品信息又被包含在很多訂單里),所以我們需要OrderItems表來當作中介,簡單的連接Order編號和Product編號。
這個數(shù)據(jù)庫并不是一個最佳實踐,它所包含的信息僅僅用來展示NHibernate是怎樣工作的。
映射業(yè)務模型
許多介紹NHibernate的文章都是以配置文件開始的,但是從另一個地方開始:映射類。映射是NHibernate的核心,而且配置也給初學者一個很大的絆腳石。當我們討論完映射,我們再回來介紹NHibernate的配置部分。
映射簡單的指定哪一個表對應哪一個類。我們把映射的類對應的表叫這個類的“映射表”。
我們在上面就已經(jīng)說了,Nhibernate不需要特定的接口或是特定的代碼寫在要映射的類里。但是它需要被聲明成Virtual,這樣可以在需要的時候創(chuàng)建代理。NHibernate文檔里討論了為什么這樣,現(xiàn)在我們把所有業(yè)務模型中的類聲明成Virtual。
映射可以同過分離的XML文件實現(xiàn),也可以通過在類屬性上添加特性來實現(xiàn)。被用于映射的XML文件可以在任何一個項目里引用。為了簡單,我們將展示其中一個方法:通過XML文件映射,映射文件需要被編譯成程序集的嵌入式資源。
你可以映射很多類在同一個映射文件中,但是通常都會為每一個類創(chuàng)建一個映射文件。這樣可以保持映射文件的短小,而且容易閱讀。
開始我們映射實驗之前,先讓我們看看Customer.hbm.xml文件。hbm.xml后綴的文件是NHibernate標準的映射文件的后綴。我們把映射文件放在Model文件下,但是我們可以把他們放在項目的任何一個地方。最關鍵的一點是將文件的 BuildAction 屬性設置為 Embedden Resource(嵌入式資源)。這個設置將會把映射文件編譯到程序集里,這樣把他們從程序中脫離出來。
映射文件都是標準的格式:
<?xml version="1.0"?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
namespace="NHibernateSimpleDemo"
assembly="NHibernateSimpleDemo">
NET技術:NHibernate 變的簡單,轉(zhuǎn)載需保留來源!
鄭重聲明:本文版權歸原作者所有,轉(zhuǎn)載文章僅為傳播更多信息之目的,如作者信息標記有誤,請第一時間聯(lián)系我們修改或刪除,多謝。