1. 程式人生 > >NHibernate原始碼淺讀 1

NHibernate原始碼淺讀 1

曾經瞭解過Hibernate, 印象很深,是個很不錯得O/R Mapping FW. 在http://nhibernate.sourceforge.net/上有個從Java移植過來得.NET版本--NHibernate(以下稱NH),不過目前還處於PreAlpha Build 2階段.

出於興趣以及學習.NET得目的, 花了兩天僅看了很小一部分程式碼:一來原始碼註釋並不豐富,二來對於Hibernate/NHibernate的使用也很不熟悉,三來有些知識點還不熟悉.

準備工作如下:
1. NHibernate PreAlpha Build 2
2. NUnit
3. NHibernate配置檔案 monitoring.dll.config

如下:


<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <section name="nhibernate" type= "System.Configuration.NameValueSectionHandler,System,Version=1.0.3300.0,Culture=neutral, PublicKeyToken=b77a5c561934e089" />
  </configSections>
  <nhibernate>
    <add key="hibernate.show_sql" value="false"/><!-- 設定是否輸出SQL語句到Console  -->
    <add key="hibernate.connection.provider" value="NHibernate.Connection.DriverConnectionProvider" />
    <add key="hibernate.dialect" value="NHibernate.Dialect.MsSql2000Dialect" /><!--設定使用SQL Server的方言,畢竟不同DB的SQL有或多或少的區別 -->
    <add key="hibernate.connection.driver_class" value="NHibernate.Driver.SqlClientDriver" /> <!-- 設定使用的DB驅動-->
    <add key= "hibernate.connection.connection_string"value="Server=zephyr;initial catalog= argus;UserID=sa;Password=zephyr;Min Pool Size=2" /> <!-- 設定連線串 -->
  </nhibernate>
</configuration>



可以看出以上是一個標準得Config檔案,一般由System.Configuration.ConfigurationSettings.GetConfig方法來讀取.
藍色部分才是真正配置NH的地方, 例子中我配置它使用SQL Server, 那些Key/Value的含義很好明白.
值得注意得是,配置檔案得檔名很重要,通常對於一個EXE得Assembly來說,是AssemblyName.Config,不過對於Dll Assembly來,對應的配置檔案為AssemblyName.dll.config 例如:
MyAssy.exe -> MyAssy.config
MyAssy.dll -> MyAssy.dll.config

我打算在我的monitoring.dll,一個用來監視效能東東中使用NH來持久化資料. 該類庫包含了一個TestCase,由NUnit來呼叫

4.將要被持久化的物件, 即Business Object(BO)

using System;
namespace Argus.Monitoring
{
public class Monitor
     {
   
//dbID & DBID 是NH必須要求的主鍵
private int dbID;
public intDBID{set{dbID=value;}get{return dbID;}}
         public string MonitorType {get{return "dummy monitor";}}
 
public double Value {get{return 12.34;} 
public string Category{get{return "this is category";}}
public string Name{get{return "this is name";}}
 
public string Instance{get{return "this is instance";}}
public string Computer{get{return "this is computer";}} <?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />}
}

這是一個被極度簡化的類,省略了Member Method,甚至Property的set方法,因為我打算先試試Insert功能,然後再嘗試Load功能

5. 寫一個該BO對應的最簡單的對映檔案

<?xml version="1.0" encoding="utf-8" ? designtimesp=19289><?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.0">
  <!-- 指明BO的全名和所在Assembly的名字以及在資料庫中對應的表名-->
  <class name="Argus.Monitoring.Monitor,monitoring" table= "record">
    <id name="DBID" type="Int32">
      <generator class="identity"/><!-- 在資料庫表中 ID列設成自動加一的主鍵-->
    </id>
    <!--若不設column屬性,則預設BO中屬性名稱和表中欄位名一致,若不指明type,則通過反射BO的屬性來得到列的資料型別-->
    <property name="Computer" type="String(50)"/>
    <property name="Category" type="String(50)"/>
    <property name="Name" column="counter" type="String(50)"/>
    <property name="Instance" type="String(50)"/>
     <!--此處BO的Value屬性被對映到data列-->
    <property name="Value" column="data" type="Double"/>
    <property name="MonitorType" type="String(50)"/>
  </class>
</hibernate-mapping>

6. 最後一步 (好累啊~~~), TestCase:
 

using System;

using NUnit.Framework;

using NHibernate;

using Argus.Monitoring;

namespace Test.Monitoring

{

[TestFixture]

public class MonitoringTest

{

[Test] public void NHibernateTest ()

{

Argus.Monitoring.Monitor m=new Argus.Monitoring.Monitor ();

NHibernate.Cfg.Configuration cfg=new NHibernate.Cfg.Configuration ();

cfg.AddXmlFile ("Argus.Monitoring.Monitor.hbm.xml");

ISession session= cfg.BuildSessionFactory ().OpenSession();

session.Save (m);

session.Close ();

}

}

}

(嘿嘿, 電影Down剛完, 休息一下了 明天將隨著Test Case的每一步,看看NH中到底發生了什麼)