[轉]NHibernate之旅(2):第一個NHibernate程式

來源:互聯網
上載者:User

標籤:des   style   blog   http   io   os   使用   ar   strong   

本節內容

  • 開始使用NHibernate
  • 1.擷取NHibernate
  • 2.建立資料庫表
  • 3.建立C#類庫項目
  • 4.設計Domain
    • 4-1.設計持久化類
    • 4-2.編寫對應檔
  • 5.資料訪問層
    • 5-1.輔助類
    • 5-2.編寫操作
  • 6.資料訪問層的測試
    • 6-1.配置NHibernate
    • 6-2.測試
  • 結語

作者註:2009-11-06已更新

開始使用NHibernate

我們親自動手,一步一步搭建一個NHibernate程式來,我以一個實際情境電子交易程式來類比,客戶/訂單/產品的經典組合。由於是第一次使用NHibernate,所以我們的目的是映射一張表並完成使用NHibernate來讀取資料,下面的一幅圖片給了我們第一印象。我們按照基本開發軟體思想的流程一步一步完成。

我使用的開發環境:Microsoft Visual Studio 2008 SP1、SQL Server 2008 Express、NHibernate 2.1.1GA。

1.擷取NHibernate

使用官方2009年10月31日最新發行的NHibernate-2.1.1.GA版本。如果你第一次使用NHibernate,先到這裡下載NHibernate最新版本(包括源碼、發布版本、參考文檔、API文檔,可選擇下載)。如果用到NHibernate的擴充項目到這裡下載獲得NHibernate Contrib最新版本。NHibernate-2.1.1.GA是.NET2.0平台的最後一個版本,關於NHibernate-2.1.1.GA的更多資訊請點擊這裡。

關於NHibernate2.1版本的一些說明:

NHibernate2.1版本改變了ByteCode消極式載入機制,有三種3種IoC架構動態代理方式,分別為:Castle架構、LinFu架構、Spring.Net架構。我們只要選擇一種,在設定檔中配置proxyfactory.factory_class節點。

如果使用Castle.DynamicProxy2動態代理,引用NHibernate.ByteCode.Castle.dll程式集並配置proxyfactory.factory_class節點為<property name="proxyfactory.factory_class"> NHibernate.ByteCode.Castle.ProxyFactoryFactory,NHibernate.ByteCode.Castle</property>

如果使用LinFu.DynamicProxy動態代理,引用NHibernate.ByteCode.LinFu.dll程式集並配置proxyfactory.factory_class節點為<property name="proxyfactory.factory_class"> NHibernate.ByteCode.LinFu.ProxyFactoryFactory,NHibernate.ByteCode.LinFu</property>

如果使用Spring.Aop動態代理,引用NHibernate.ByteCode.Spring.dll程式集並配置proxyfactory.factory_class節點為<property name="proxyfactory.factory_class"> NHibernate.ByteCode.Spring.ProxyFactoryFactory,NHibernate.ByteCode.Spring</property>

另外NHibernate2.1要求.NET2.0 SP1以上版本 (System.DateTimeOffset),請使用VS2005的,務必打上Sp1補丁。推薦使用VS2008以上版本。

2.建立資料庫表

由於第一次使用,還是按照我們傳統的從資料庫表配置吧。

開啟SQL Server Management Studio Express,建立一個新的資料庫NHibernateSample,建立四個表:分別為客戶表、訂單表、訂單產品表、產品表。

3.建立C#類庫項目

由於是我們第一個程式,所以我沒有按照Domain Driver Design方法去設計這個程式,按照大家的常規思想來實現的,以後有機會再介紹Domain Driver Design設計。

注意為什麼建立C#類庫項目呢?在現在軟體設計中,大多數都是採用多層架構來設計, 比較經典的三層架構(頁面展示層,商務邏輯層,資料訪問層)通常而言商務邏輯層和資料訪問層都是使用類庫設計,頁面展示層用Web應用程式設計,它引用商務邏輯層和資料訪問層類庫DLL程式集。

使用VS2008建立C#類庫的項目,命名為NHibernateSample。開啟專案檔夾,在其專案檔目錄上建立SharedLibs檔案夾,把下載NHibernate相關組件檔拷貝到SharedLibs檔案夾下。如,這裡我選擇Castle架構動態代理:

建立項目,結構如下:

  • Domain(領域模型):用於持久化類和O/R Mapping操作
  • Data(Data Access Layer資料訪問層):定義對象的CRUD操作
  • Data.Test(資料訪問層測試):對資料訪問層的測試,這裡我使用Nunit單元測試架構
  • Web:Web頁面(這篇文章中暫未實現,請參考我的部落格其他文章)
項目引用
  • Domain:引用Iesi.Collections.dll程式集(Set集合在這個程式集中)和Castle動態代理
  • Data:引用NHibernate.dll和Iesi.Collections.dll程式集和動態代理相關程式集,Domain引用
  • Data.Test:引用NHibernate.dll和Iesi.Collections.dll程式集,nunit.framework.dll程式集(測試架構),Domain和Data引用
4.設計Domain4-1.編寫持久化類

按簡單傳統.NET對象(POCOs,Plain Old CLR Objects(Plain Ordinary CLR Objects))模型編程時需要持久化類。在NHibernate中,POCO通過.NET的屬性機制存取資料,就可以把它映射成為資料庫表。

現在為Customer編寫持久化類來映射成為資料庫表。建立一個Customer.cs類檔案:

namespace NHibernateSample.Domain.Entities{    public class Customer    {        public virtual int Id { get; set; }        public virtual string FirstName { get; set; }        public virtual string LastName { get; set; }    }}
規則
  • NHibernate使用屬性的getter和setter來實現持久化。
  • 屬性可設定為public、internal、protected、protected internal或private
注意NHibernate預設使用代理功能,要求持久化類不是sealed的,而且其公用方法、屬性和事件聲明為virtual。在這裡,類中的欄位要設定為virtual,否則出現“failed: NHibernate.InvalidProxyTypeException : The following types may not be used as proxies: NHibernateSample.Domain.Entities.Customer: method get_Id should be virtual,method set_Id should be virtual”異常。4-2.編寫對應檔 小提示我們要為Microsoft Visual Studio 2008添加編寫NHibernate設定檔智能提示的功能。只要在下載的NHibernate裡找到configuration.xsd和nhibernate-mapping.xsd兩個檔案並複製到X:\Program Files\Microsoft Visual Studio 9.0\Xml\Schemas目錄即可。

NHibernate要知道怎樣去載入和儲存持久化類的對象。這正是NHibernate對應檔發揮作用的地方。對應檔包含了對象/關係映射所需的中繼資料。中繼資料套件含持久化類的聲明和屬性到資料庫的映射。對應檔告訴NHibernate它應該訪問資料庫裡面的哪個表及使用表裡面的哪些欄位。

這裡,我為Customer.cs類編寫對應檔。建立一XML檔案,命名為Customer.hbm.xml:

<?xml version="1.0" encoding="utf-8" ?><hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"   assembly="NHibernateSample.Domain"   namespace="NHibernateSample.Domain.Entities">    <class name ="Customer">    <id name="Id" column ="CustomerId">      <generator class ="native"/>    </id>    <property name ="FirstName"/>    <property name ="LastName"/>  </class></hibernate-mapping>
注意XML檔案的預設產生操作為“內容”,這裡需要修改為“內嵌資源”產生,因為NHibernate是通過尋找程式集中的資源檔映射實體,使用.NET Reflector查看程式集:

否則出現“ failed: NHibernate.MappingException : No persister for: NHibernateSample.Domain.Entities.Customer”異常。5.編寫資料訪問層5-1.輔助類

我們現在可以開始NHibernate了。首先,我們要從ISessionFactory中擷取一個ISession(NHibernate的工作單元)。ISessionFactory可以建立並開啟新的Session。一個Session代表一個單線程的單元操作。 ISessionFactory是安全執行緒的,很多線程可以同時訪問它。ISession不是安全執行緒的,它代表與資料庫之間的一次操作。ISession通過ISessionFactory開啟,在所有的工作完成後,需要關閉。 ISessionFactory通常是個安全執行緒的全域對象,只需要被執行個體化一次。我們可以使用GoF23中的單例(Singleton)模式在程式中建立ISessionFactory。這個執行個體我編寫了一個輔助類NHibernateHelper 用於建立ISessionFactory並配置ISessionFactory和開啟一個新的Session單線程的方法,之後在每個資料操作類可以使用這個輔助類建立ISession 。

public class NHibernateHelper{    private ISessionFactory _sessionFactory;    public NHibernateHelper()    {        _sessionFactory = GetSessionFactory();    }    private ISessionFactory GetSessionFactory()    {        return (new Configuration()).Configure().BuildSessionFactory();    }    public ISession GetSession()    {        return _sessionFactory.OpenSession();    }}
5-2.編寫操作

在Data中建立一類NHibernateSample.cs,編寫一方法GetCustomerId用於讀取客戶資訊。在編寫方法之前,我們需要初始化Session。

protected ISession Session { get; set; }public NHibernateSample(ISession session){    Session = session;}

NHibernate有不同的方法來從資料庫中取回對象。最靈活的方式是使用NHibernate查詢語言(HQL),是完全基於物件導向的SQL。

public void CreateCustomer(Customer customer){    Session.Save(customer);    Session.Flush();}public Customer GetCustomerById(int customerId){    return Session.Get<Customer>(customerId);}
6.編寫資料訪問層的測試6-1.配置NHibernate

我們可以幾種方法來儲存NHibernate的配置,具體以後來介紹,這裡我們使用hibernate.cfg.xml檔案來配置,不過不必擔心,這個檔案我們可以在src\NHibernate.Config.Templates檔案夾下找到,直接複製到Data.Test中修改一下配置資訊和檔案輸出屬性就可以了。

<?xml version="1.0" encoding="utf-8"?><hibernate-configuration  xmlns="urn:nhibernate-configuration-2.2" >    <session-factory>        <property name="connection.driver_class">NHibernate.Driver.SqlClientDriver</property>        <property name="connection.connection_string">            Data Source=.\SQLEXPRESS;Initial Catalog=NHibernateSample;      Integrated Security=True;Pooling=False        </property>        <property name="adonet.batch_size">10</property>        <property name="show_sql">true</property>        <property name="dialect">NHibernate.Dialect.MsSql2005Dialect</property>        <property name="use_outer_join">true</property>        <property name="command_timeout">10</property>        <property name="query.substitutions">true 1, false 0, yes ‘Y‘, no ‘N‘</property>     <property name="proxyfactory.factory_class">NHibernate.ByteCode.Castle.ProxyFactoryFactory,       NHibernate.ByteCode.Castle</property>    <mapping assembly="NHibernateSample.Domain"/>        </session-factory></hibernate-configuration>
注意XML檔案的預設“複製到輸出目錄”為“不複製”,這裡需要修改為“始終複製”。否則出現“failed: NHibernate.Cfg.HibernateConfigException : An exception occurred during configuration of persistence layer. ----> System.IO.FileNotFoundException : 未能找到檔案“NHibernateSample\NHibernateSample.Data.Test\bin\Debug\hibernate.cfg.xml””異常。6-2.測試

好了,終於可以使用我們的方法了,這裡建立一個測試類別NHibernateSampleFixture.cs來編寫測試案例:調用NHibernateSample類中GetCustomerId方法查詢資料庫中CustomerId為1的客戶,判斷返回客戶的Id是否為1。

[TestFixture]public class NHibernateSampleFixture{    private NHibernateSample _sample;    [TestFixtureSetUp]    public void TestFixtureSetup()    {        _sample = new NHibernateSample();    }    [Test]    public void GetCustomerByIdTest()    {        var tempCutomer = new Customer {FirstName = "李", LastName = "永京"};        _sample.CreateCustomer(tempCutomer);        Customer customer = _sample.GetCustomerById(1);        int customerId = customer.Id;        Assert.AreEqual(1,customerId);    }}

我們使用TestDriven.NET測試一下這個方法:OK,測試通過。這裡我使用NHibernate監視器NHibernate Profiler查看結果:

[轉]NHibernate之旅(2):第一個NHibernate程式

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.