簡介
在今日的企業環境中,把面向對象的軟體和關係資料庫一起使用可能是相當麻煩和浪費時間的.NHibernate不僅僅管理.NET類到資料庫表的映射(包括.NET 數據類型到SQL數據類型的映射),還提供數據查詢和獲取數據的方法,可以大幅度減少開發時人工使用SQL和ADO.NET處理數據的時間。
NHibernate的目標主要是用於與數據持久化相關的編程任務,能夠使開發人員從原來枯燥的SQL語句的編寫中解放出來,解放出來的精力可以讓開發人員投入到業務邏輯的實現上。對於以數據為中心的程式,開發人員往往是在資料庫中使用存儲過程來實現商業邏輯,這種情況下NHibernate可能不是最好的解決方案,但對於那些基於.NET,並且能夠實現OO業務模型和商業邏輯的中間層套用,NHibernate是最有用的。NHibernate可以幫助用戶消除或者包裝那些針對特定廠商的SQL代碼,並且幫用戶把結果集從表格式的表示形式轉換成一系列的對象。
Hibernate是一個目前套用的最廣泛的開放原始碼的對象關係映射框架,它對Java的JDBC(類似於ADO.Net)進行了非常輕量級的對象封裝,使得程式設計師可以隨心所欲的使用對象編程思維來操縱資料庫,目前在國內Java開發界已經頗為流行,Hibernate+Spring往往是很多Java公司招聘的要求。而NHibernate,顧名思義,如同NUnit,NAnt一樣,是基於.Net的Hibernate實現,但是目前介紹NHibernate的資料非常少,缺少一個系統完整的教程來全面的展現和深入NHibernate,而且現在NHibernate的文檔又殘缺不全,少的可憐,很多NHibernate的學習者往往都是通過Hibernate的文檔來學習,但是畢竟不是所有的.Net開發者都熟悉Java,也不是所有的人都有精力有時間去學習Java。
NHibernate 是一個基於.Net 的針對關係型資料庫的對象持久化類庫。Nhibernate 來源於非常優秀的基於Java的Hibernate 關係型持久化工具。
NHibernate 從資料庫底層來持久化你的.Net 對象到關係型資料庫。NHibernate 為你處理這些,遠勝於你不得不寫SQL去從資料庫存取對象。你的代碼僅僅和對象關聯,NHibernat 自動產生SQL語句,並確保對象提交到正確的表和欄位中去。
體系結構
NHibernate體系結構如圖1-51所示。它體現了NHibernate如何使用資料庫和配置檔案數據來為應用程式提供持久化服務(和持久化的對象)。
SessionFactory(NHibernate.IsessionFactory):它是Session的工廠,是ConnectionProvider的客戶。可以持有一個可選的(第二級)數據快取,可以在進程級別或集群級別保存的可以在事物中重用的數據。
會話(NHibernate.ISession):單執行緒,生命期較短的對象,代表應用程式和持久化層之間的一次對話。封裝了一個ADO.NET連線,也是Transaction的工廠。保存有必需的(第一級)持久化對象的快取,用於遍歷對象圖,或者通過標識符查找對象。
持久化對象(Persistent)及其集合(Collections):生命期較短的單執行緒的對象,包含了持久化狀態和商業功能。這些可能是普通的對象,唯一特別的是現在從屬於且僅從屬於一個Session。一旦Session被關閉,它們都將從Session中取消聯繫,可以在任何程式層自由使用(比如,直接作為傳送到表現層的DTO,數據傳輸對象)。
臨時對象(Transient Object)及其集合(Collection):目前沒有從屬於一個Session的持久化類的實例。這些可能是剛剛被程式實例化,還沒有來得及被持久化,或者是被一個已經關閉的Session實例化。
事務Transaction (NHibernate.ITransaction):(可選)單執行緒,生命期較短的對象,應用程式用其來表示一批工作的原子操作,它是底層的ADO.NET事務的抽象。一個Session在某些情況下可能跨越多個Transaction事務。
ConnectionProvider(NHibernate.Connection.ConnectionProvider):(可選)ADO.NET連線的工廠。從底層的IDbConnection抽象而來。對應用程式不可見,但可以被開發者擴展/實現。
TransactionFactory(net.sf.hibernate.TransactionFactory):(可選)事務實例的工廠。對應用程式不可見,但可以被開發者擴展/實現。
持久化類
持久化類是應用程式用來解決商業問題的類(比如,在電子交易程式中的Customer和Order)。持久化類是暫時存在的,實例會被持久性保存於資料庫中。
如果這些類符合簡單的規則,NHibernate能夠工作得最好,這些規則就是Plain Old CLR Object(POCO,簡單傳統CLR對象)編程模型。
POCO簡單示例(用一個類描述一隻貓)如下:
public class Cat
{
private long _id; // 標識符
private string _name; // 名字
private DateTime _birthdate; // 出生日期
private Cat _mate; // 貓的配對
private Set _kittens; // 貓仔
private Color _color; // 顏色
private char _sex; // 性別
private float _weight; // 體重
public long Id // 標識符屬性
{
get
{return _id; }
set
{ _id = value; }
}
public string Name // 名字屬性
{
get
{ return _name; }
set
{ _name = value; }
}
public DateTime Birthdate // 出生日期屬性
{
get
{ return _birthdate; }
set
{ _birthdate = value; }
}
public Cat Mate // 貓的配對屬性
{
get
{ return _mate; }
set
{ _mate = value; }
}
public Set Kittens // 貓仔屬性
{
get
{ return _kittens; }
set
{ _kittens = value; }
}
public Color Color // 顏色屬性
{
get
{ return _color; }
set
{ _color = value; }
}
public char Sex // 性別屬性
{
get
{ return _sex; }
set
{ _sex = value; }
}
public float Weight // 體重屬性
{
get
{ return _weight; }
set
{ _weight = value; }
}
}
規則
為持久化欄位聲明訪問器(getters和setters)。
Cat為它的所有可持久化欄位聲明了getters和setters訪問器。用訪問器來替代直接訪問欄位是個好習慣。也可以通過欄位(field)來使用NHibernate。屬性不一定需要聲明為public的。NHibernate可以對default、protected、internal或private的屬性執行持久化.
實現一個默認的構造方法(constructor):Cat有一個顯式的無參數默認構造方法。所有的持久化類都必須具有一個默認的構造方法(可以不是public的),這樣NHibernate就可以使用Constructor.Invoke()來實例化它們.
提供一個標識屬性(identifier property)(可選).
建議使用不是sealed的類(可選).
映射
對象和關係資料庫之間的映射是用一個XML文檔(XML document)來定義的。這個映射文檔被設計為易讀的,並且可以手工修改。映射語言是以.NET為中心的,意味著映射是按照持久化類的定義來創建的,而非表的定義。在Hibernate中XML映射文檔可以手動定義,也有一些工具來輔助生成,包括Xdoclet、Middlegen和AndroMDA,但是在NHibernate文檔中並沒有上述的輔助工具,不過可以採用MyGeneration這樣的代碼生成工具來生成XML配置文檔。
雖然NHibernate目前不是非常的成熟,還沒有達到實用化的水平,它經常在負荷有些大的時候崩潰,但是它脫胎於在Java社區有著巨大影響力的Hibernate,而且NHibernate在實際套用方面確實體現出了它的優勢,基於上述原因NHibernate一定會被越來越多的開發人員所接受,而且一定會被標準化。