NHibernate文檔翻譯 第1章—-快速起步

來源:互聯網
上載者:User

註:本文中使用的是NH1.0.1.0版本,其他版本配置可能略有不同。

範例程式碼下載。

資料庫指令碼下載

一、體繫結構

首先我們來看看NHibernate的體繫結構:

NHibernate是資料庫和應用程式之間的持久化層,應用程式和NHibernate通過持久化(Persistent)對象聯絡在一起。NHibernate使用app.config或者web.config和對應檔進行設定。

下面來看看怎麼使用NHibernate API的一個最小子集。

下面是圖中一些對象的定義:

Configuration(NHibernate.Cfg.Configuration)

設定物件,用來指定用來出建立ISessionFactory的屬性和對應檔。(圖中沒有此對象)
SessionFactory (NHibernate.ISessionFactory)

Session的工廠。

會話,Session (NHibernate.ISession)

代表應用程式和持久化層之間的一次對話。封裝了一個ADO.NET串連。也是Transaction的工廠。儲存有必需的(第一級)持久化對象的緩衝,用於遍曆對象圖,或者通過標識符尋找對象。

事務Transaction (NHibernate.ITransaction)

(可選) 單線程,生命期短促的對象,應用程式用它來表示一批工作的原子操作。是底層的ADO.NET事務的抽象。一個Session某些情況下可能跨越多個Transaction 事務。

 

二、範例程式碼

我們看看他們是如何協同工作的,請看下面的代碼。

程式碼範例(未改變資料庫中的資料,查詢操作):

//配置ConfigurationConfiguration cfg = new Configuration().Configure();//建立ISessionFactoryISessionFactory factory = cfg.BuildSessionFactory();//開啟ISessionISession session = factory.OpenSession();session=factory.OpenSession();try{在這裡添加操作}finally{session.Close();}

Configuration的Configure方法,將使用應用程式的設定檔或者hibernate.cfg.xml檔案的<hibernate-configuration>節點進行配置,傳回值是一個配置好了的Configuration對象的執行個體。

然後這個Configuration通過BuildSessionFactory方法建立ISessionFactory的執行個體。

ISessionFactory的執行個體通過OpenSession開啟一個ISession的執行個體,用這個執行個體完成資料庫的操作,然後關閉它。

如果你的代碼中需要事務,只需要把代碼稍微修改一下。

程式碼範例(改變了資料庫中的資料,資料的增刪改):

//配置ConfigurationConfiguration cfg = new Configuration().Configure();//建立ISessionFactoryISessionFactory factory = cfg.BuildSessionFactory();//定義事務ITransaction tx = null;//開啟ISessionISession session = factory.OpenSession();try{//開始事務tx = session.BeginTransaction();在這裡添加操作tx.Commit();}catch(HibernateException ex){if (tx!=null) tx.Rollback();throw ex;}finally{//關閉ISessionsession.Close();}

我一般在不影響資料的方法(例如:查詢)中不包含事務,而影響資料的方法(例如:增刪改)使用事務。

 

三、設定檔

前面提到Configuration的Configure方法需要用到應用程式的設定檔或者hibernate.cfg.xml檔案,這裡我使用hibernate.cfg.xml設定檔,在下一章我們再探討使用應用程式的設定檔和其他的配置方法。

這是一個典型的設定檔:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-configuration xmlns="urn:nhibernate-configuration-2.0">
<session-factory name="DDLLY.MyDoc.NHibernate.QuickStart">
<!-- 屬性 -->
<property name="connection.provider">NHibernate.Connection.DriverConnectionProvider</property>
<property name="connection.driver_class">NHibernate.Driver.SqlClientDriver</property>
<property name="connection.connection_string">server=.;database=user;uid=sa;pwd=sa;</property>
<property name="show_sql">false</property>
<property name="dialect">NHibernate.Dialect.MsSql2000Dialect</property>
<property name="use_outer_join">true</property>
<property name="query.substitutions">true 1, false 0, yes 'Y', no 'N'</property>
<!-- 對應檔 -->
<mapping assembly="DDLLY.MyDoc.NHibernate.QuickStart" />
</session-factory>
</hibernate-configuration>

屬性connection.provider設定了資料庫連接提供者(一般不需要更改,除非你決定自己實現提供者)。

connection.driver_class設定了資料庫的的驅動類(這裡設定了SqlServer的驅動類)。

connection.connection_string是資料庫的連接字串。

show_sql設定是否在運行時是否在控制台顯示正在執行的SQL語句(這個屬性在偵錯工具時很有用)。

dialect是NHibernate方言, 可以讓NHibernate使用某些特定的資料庫平台的特性。

use_outer_join在後面的章節會有介紹。

query.substitutions,把NHibernate查詢中的一些短語替換為SQL短語(比如說短語可能是函數或者字元)。

mapping節點設定了將使用到的對應檔,現在的設定方法是使用"DDLLY.MyDoc.NHibernate.QuickStart“中所有的對應檔。

 

四、對應檔

ISession怎麼知道和資料庫的哪張表哪個欄位打交道,以及怎麼把表和實體物件聯絡起來呢?靠的就是對應檔。

假設我們有個很簡單的例子,我們有如下的一張表需要進行資料操作(欄位和表含義一看就知道,我就不羅嗦了):

CREATE TABLE [dbo].[users] ([Id] [int] IDENTITY (1, 1) NOT NULL ,[UserName] [nvarchar] (64)  NOT NULL ,[Password] [varchar] (32)  NOT NULL ,[Email] [varchar] (64)  NULL )

我們設定它的對應檔和相應的代碼檔案:

<?xml version="1.0" encoding="utf-8" ?> 
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.0">
<class name="DDLLY.MyDoc.NHibernate.QuickStart.User, DDLLY.MyDoc.NHibernate.QuickStart" table="users">
<id name="Id" type="Int32">
<generator class="identity" />
</id>

<property name="UserName" type="String"/>
<property name="Password" type="String"/>
<property name="Email" type="String"/>
</class>
</hibernate-mapping>
public class User{public User(){}private int m_Id;private string m_UserName;private string m_Password;private string m_Email;public int Id {get { return m_Id; }set { m_Id = value; }}public string UserName {get { return m_UserName; }set { m_UserName = value; }}public string Password {get { return m_Password; }set { m_Password = value; }}public string Email {get { return m_Email; }set { m_Email = value; }}}

<class name="DDLLY.MyDoc.NHibernate.QuickStart.User, DDLLY.MyDoc.NHibernate.QuickStart" table="users"> 表示對應檔對應的類檔案是DDLLY.MyDoc.NHibernate.QuickStart程式集中的 DDLLY.MyDoc.NHibernate.QuickStart.User類,逗號後面是表示程式集。對應的資料庫表為users。

<id name="Id" type="Int32">
<generator class="identity" />
</id>

表示Id是主鍵欄位,generator是產生器,這裡是使用SqlServer中內建識別欄位來產生。

property定義了其他的欄位。

 

五、完成代碼

好了,下面我們可以開始對資料進行操作了。

我們來看看ISession為我們提供的常用方法。

Load:讀取實體物件

Find:通過HQL尋找實體物件

Save:儲存實體物件

Delete:刪除實體物件

用這些方法我們便可以完成對資料庫的增刪改查的操作了。下面是我完成的代碼(使用NUnit進行測試)。

using System;using System.Collections;using System.Data;using System.Data.SqlClient;using NHibernate;using NHibernate.Cfg;using NUnit.Framework;namespace DDLLY.MyDoc.NHibernate.QuickStart{/// <summary>/// User測試類別/// </summary>[TestFixture]public class UserFixture{#region 常量//連接字串const string CONNECTIONSTRING="server=.;database=user;uid=sa;pwd=sa;";#endregion#region SetUp和TearDown[SetUp]public void SetUp() {//添加名為LLY,密碼為123456的使用者,因為這是資料庫的第一條記錄,所以資料庫標識為1string SetUpSql="INSERT INTO users([UserName],[Password]) VALUES('LLY','123456')";SqlExecuteNonQuery(SetUpSql);}[TearDown]public void TearDown() {//清空users表,並把標識(identity)清零string TearDownSql="TRUNCATE TABLE users";SqlExecuteNonQuery(TearDownSql);}#endregion#region 私人方法/// <summary>/// 執行SQL語句/// </summary>/// <param name="sql">SQL語句</param>private void SqlExecuteNonQuery(string sql){SqlConnection con=new SqlConnection(CONNECTIONSTRING);con.Open();SqlCommand cmd=new SqlCommand();cmd.Connection=con;cmd.CommandText=sql;cmd.ExecuteNonQuery();con.Close();}#endregion#region 測試方法/// <summary>/// 測試讀取使用者/// </summary>[Test]public void TestLoadUser(){User user=null;//配置ConfigurationConfiguration cfg = new Configuration().Configure();//建立ISessionFactoryISessionFactory factory = cfg.BuildSessionFactory();//開啟ISessionISession session = factory.OpenSession();session=factory.OpenSession();try{user=session.Load(typeof(User),1) as User;  }finally{session.Close();}//************************資料檢查*****************************//檢查Assert.IsNotNull(user,"沒有找到ID為1的使用者!");Assert.AreEqual("LLY",user.UserName,"沒有找到名字為LLY的使用者!");}/// <summary>/// 測試尋找使用者/// </summary>[Test]public void TestFindUser(){IList userlist=null;//配置ConfigurationConfiguration cfg = new Configuration().Configure();//建立ISessionFactoryISessionFactory factory = cfg.BuildSessionFactory();//開啟ISessionISession session = factory.OpenSession();string hql="from User as u where u.UserName='LLY'";session=factory.OpenSession();try{userlist=session.Find(hql);}finally{session.Close();}//************************資料檢查*****************************//檢查Assert.AreEqual(1,userlist.Count,"名字為LLY的使用者個數不為1!");}/// <summary>/// 測試添加使用者/// </summary>[Test]public void TestAddUser() {User newUser = new User();//配置ConfigurationConfiguration cfg = new Configuration().Configure();//建立ISessionFactoryISessionFactory factory = cfg.BuildSessionFactory();//定義事務ITransaction tx = null;//開啟ISessionISession session = factory.OpenSession();try{//開始事務tx = session.BeginTransaction();newUser.UserName = "DDL";newUser.Password = "123456";newUser.Email = "DDLLY@tom.com";// 儲存新使用者session.Save(newUser);tx.Commit();}catch(HibernateException ex){if (tx!=null) tx.Rollback();throw ex;}finally{//關閉ISessionsession.Close();}//************************資料檢查*****************************IList userlist=null;string hql="from User as u where u.UserName='DDL'";session=factory.OpenSession();try{userlist=session.Find(hql);}finally{session.Close();}//檢查是否有且僅有一個名稱為DDL的使用者Assert.AreEqual(1,userlist.Count,"名字為DDL的使用者個數不為1!");}/// <summary>/// 測試刪除使用者/// </summary>[Test]public void TestDeleteUser(){IList userlist=null;User user=null;//配置ConfigurationConfiguration cfg = new Configuration().Configure();//建立ISessionFactoryISessionFactory factory = cfg.BuildSessionFactory();//定義事務ITransaction tx = null;//開啟ISessionISession session = factory.OpenSession();try{//開始事務tx = session.BeginTransaction();user=session.Load(typeof(User),1) as User;session.Delete(user);tx.Commit();}catch(HibernateException ex){if (tx!=null) tx.Rollback();throw ex;}finally{session.Close();}//************************資料檢查*****************************string hql="from User as u where u.UserName='LLY'";session=factory.OpenSession();try{userlist=session.Find(hql);}finally{session.Close();}//檢查Assert.AreEqual(0,userlist.Count,"名字為LLY的使用者沒有被刪除!");}/// <summary>/// 測試更新使用者/// </summary>[Test]public void TestUpdateUser(){User user=null;//配置ConfigurationConfiguration cfg = new Configuration().Configure();//建立ISessionFactoryISessionFactory factory = cfg.BuildSessionFactory();//定義事務ITransaction tx = null;//開啟ISessionISession session = factory.OpenSession();try{//開始事務tx = session.BeginTransaction();user=session.Load(typeof(User),1) as User;user.Password="123";session.Update(user);tx.Commit();}catch(HibernateException ex){if (tx!=null) tx.Rollback();throw ex;}finally{session.Close();}//************************資料檢查*****************************session=factory.OpenSession();try{user=session.Load(typeof(User),1) as User;}finally{session.Close();}//檢查Assert.IsNotNull(user,"沒有找到名字為LLY的使用者!");Assert.AreEqual("123",user.Password,"沒有找到名字為LLY的使用者!");}#endregion}}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.