程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> NHibernate之旅(2):第一個NHibernate程序

NHibernate之旅(2):第一個NHibernate程序

編輯:關於.NET

本節內容

開始使用NHibernate

1.獲取NHibernate

2.建立數據庫表

3.創建C#類庫項目

4.編寫DomainModel層

4-1.編寫持久化類

4-2.編寫映射文件

5.編寫數據訪問層

5-1.輔助類

5-2.編寫操作

6.編寫數據訪問層的測試

6-1.配置NHibernate

6-2.測試

結語

開始使用NHibernate

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

我使用的開發環境:Microsoft Visual Studio 2008 SP1、SQL Server 2008 Express、NHibernate 2.0最新版。

1.獲取NHibernate

使用官方2008年9月29日最新發布的NHibernate-2.0.1.GA版本。你可以到這裡下載獲得NHibernate最新版本。

2.建立數據庫表

打開SQL Server Management Studio,新建一個新的數據庫NHibernateSample,創建四個表:分別為客戶表、訂單表、訂單產品表、產品表。

注:源碼中附有創建數據庫腳本。

3.創建C#類庫項目注意為什麼創建C#類庫項目呢?在現在軟件設計中,大多數都是采用多層架構來設計,比較經典的三層架構(頁面表示層,業務邏輯層,數據訪問層)通常而言業務邏輯層和數據訪問層都是使用類庫設計,頁面表示層用Web應用程序設計,它引用業務邏輯層和數據訪問層類庫DLL程序集。

使用VS2008創建C#類庫的項目,命名為NHibernateSample。打開項目文件夾,在其項目文件目錄上新建lib文件夾,把下載NHibernate相關程序集文件拷貝到lib文件夾下。如下圖:

創建項目,結構如下:

DomainModel(域模型):用於持久化類和O/R Mapping操作

DAL(Data Access Layer數據訪問層):定義對象的CRUD操作

DAL.Test(數據訪問層測試):對數據訪問層的測試,這裡我使用Nunit單元測試框架

項目引用

DomainModel:引用Iesi.Collections.dll程序集(Set集合在這個程序集中)

DAL:引用NHibernate.dll和Iesi.Collections.dll程序集,DomainModel層引用

DAL.Test:引用NHibernate.dll和Iesi.Collections.dll程序集,nunit.framework.dll程序集(測試框架),DomainModel層和DAL層引用

4.編寫DomainModel層4-1.編寫持久化類

按簡單傳統.NET對象(POCOs,Plain Old CLR Objects(Plain Ordinary CLR Objects))模型編程時需要持久化類,也可以說是DTO(Data Transfer Object,數據傳送對象)模式(這是迄今為止可以工作的最簡單方式)。在NHibernate中,POCO通過.NET的屬性機制存取數據,就可以把它映射成為數據庫表。

現在為Customer編寫持久化類來映射成為數據庫表。新建一個Customer.cs類文件:

namespace DomainModel.Entities
{
  public class Customer
  {
    public virtual int CustomerId { 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: DomainModel.Entities.Customer: method get_CustomerId should be virtual,method set_CustomerId 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\SchemasX:\Program Files\Microsoft Visual Studio 9.0\Xml\Schemas目錄即可。

NHibernate要知道怎樣去加載和存儲持久化類的對象。這正是NHibernate映射文件發揮作用的地方。映射文件包含了對象/關系映射所需的元數據。元數據包含持久化類的聲明和屬性到數據庫的映射。映射文件告訴NHibernate它應該訪問數據庫裡面的哪個表及使用表裡面的哪些字段。

這裡,我為Customer.cs類編寫映射文件,具體怎麼編寫O/R Mapping文件,請參考NHibernate文檔。新建一XML文件,命名為Customer.hbm.xml:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
  assembly="DomainModel" namespace="DomainModel">
 <class name ="DomainModel.Entities.Customer,DomainModel" table="Customer">
  <id name="CustomerId" column="CustomerId" type="Int32" unsaved-value="0">
   <generator class ="native"></generator>
  </id>
  <property name="Firstname" column ="Firstname" type="string" length="50" not-null="false"/>
  <property name ="Lastname" column="Lastname" type="string" length="50" not-null="false"/>
 </class>
</hibernate-mapping>

注意XML文件的默認生成操作為“內容”,這裡需要修改為“嵌入的資源”生成,使用.NET Reflector查看程序集:

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

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

public class SessionManager
{
  private ISessionFactory _sessionFactory;
  public SessionManager()
  {
    _sessionFactory = GetSessionFactory();
  }
  private ISessionFactory GetSessionFactory()
  {
    return (new Configuration()).Configure().BuildSessionFactory();
  }
  public ISession GetSession()
  {
    return _sessionFactory.OpenSession();
  }
}

5-2.編寫操作

在DAL層新建一類NHibernateSample.cs,編寫一方法GetCustomerId用於讀取客戶信息。在編寫方法之前,我們需要初始化Session。

private ISession _session;
public ISession Session
{
  set
  {
    _session = value;
  }
}
public NHibernateSample(ISession session)
{
  _session = session;
}

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

public Customer GetCustomerById(int customerId)
{
  return _session.Get<Customer>(customerId);
}

6.編寫數據訪問層的測試

6-1.配置NHibernate

我們可以幾種方法來保存NHibernate的配置,具體以後來介紹,這裡我們使用hibernate.cfg.xml文件來配置,不過不必擔心,這個文件我們可以在src\NHibernate.Test文件夾下找到,直接復制到DAL.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>
  <mapping assembly="DomainModel"/>  
  </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。

using NUnit.Framework;
using DomainModel.Entities;
using NHibernate;
namespace DAL.Test
{
  [TestFixture]
  public class NHibernateSampleFixture
  {
    private ISession _session;
    private SessionManager _helper;
    private NHibernateSample _sample;
    [TestFixtureSetUp]
    public void TestFixtureSetup()
    {
      _helper = new SessionManager();
    }
    [SetUp]
    public void Setup()
    {
      _session = _helper.GetSession();
      _sample = new NHibernateSample(_session);
    }
    [Test]
    public void GetCustomerByIdTest()
    {
      Customer customer = _sample.GetCustomerById(1);
      int customerId = customer.CustomerId;
      Assert.AreEqual(1,customerId);
    }
  }
}

我們使用TestDriven.NET測試一下這個方法:OK,測試通過,還輸出了SQL語句(注:我配置NHibernate時設置了show_sql=true輸出SQL語句)。

結語

在這篇文章中,我們使用NHibernate來構建了一個最基本的項目,沒有體現NHibernate更多細節,只描繪了NHibernate的基本面目。當然使用NHibernate有各種各樣的程序架構,我按照一般模式構建的。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved