NHibernate:教你如何搭建數據訪問層?


什么是NHibernate

NHibernate 是一個基於.net 的針對關系型數據庫的對象持久化類庫。NHibernate 來源於非常優秀的基於Java的Hibernate 關系型持久化工具。
NHibernate 從數據庫底層來持久化你的.net 對象到關系型數據庫。NHibernate 為你處理這些,遠勝於你不得不寫SQL去從數據庫存取對象
。你的代碼僅僅和對象關聯,NHibernat 自動產生SQL語句,並確保對象提交到正確的表和字段中去。

這篇文檔意在讓你盡可能快的開始使用NHibernate。它將介紹如何持久化一個簡單的對象到一張表里,完成對表的操作。

開發的過程

我們將進行以下步驟:
1.新建一個將要持久化.net對象的表
2.構建一個需要被持久化的.net類
3.構建一個可以讓NHibernate知道如何持久化對象屬性的映射文件
4.構建一個讓NHibernate知道如何連接數據庫的配置文件
5.使用NHibernate的API
6.測試

第一步:寫構建表的SQL

這里我們將使用的是一個非常簡單的例子。假設你正在為你的網站開發一個基本的用戶管理子系統。我們將使用如下的一張User表(假定你已經設置好一個數據庫—例子里我稱它為test)。

CREATE TABLE users (
LogonID integer not null ,
Name nvarchar(40) default NULL,
Password nvarchar(20) default NULL,
EmailAddress nvarchar(40) default NULL,
LastLogon datetime default NULL,
PRIMARY KEY (LogonID)
)

我使用的是sqlite, 但也可以使用任何數據庫,只要你有關於它們的基於.net數據提供驅動程序。我們將得到一個含有LogonID,Name, Password, Email 和LastLogon的表. 經過以上標准步驟,我們下一步是寫一個.net類處理一個給定的User對象。

第二步:產生一個.Net 類文件

當內存中有一堆User對象的時候,我們需要某種對象去保存它們。NHibernate通過對象屬性的反射來工作,因此我們需要添加我們希望持久化的對象屬性。一個可以被NHibernate持久化的類應該看起來象下面的樣子:

using System;

namespace NHibernate.Domain
{
    public class User
    {
        public virtual int Id { get; set; }

        public virtual string UserName { get; set; }

        public virtual string Password { get; set; }

        public virtual string EmailAddress { get; set; }

        public virtual DateTime LastLogon { get; set; }
    }
}

第三步:寫映射文件

現在我們有數據表和需要去映射它的.net類。我們需要一種方式去讓NHibernate知道如何從一個映射到另一個。這個任務依賴於映射文件來完成。最易於管理的辦法是為每一個類寫一個映射文件,如果你命名它是YourObject.hbm.xml 並且把它放在和類的同一個目錄里,NHiberante將會使得事情簡單起來。下面是一個User.hbm.xml的例子:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="NHibernate.Domain" namespace="NHibernate.Domain">
  <class name="NHibernate.Domain.User,NHibernate.Domain" table="users" >
    <id name="Id" column="LogonId" type="int" unsaved-value="0">
      <generator class="increment"/>
    </id>
    <property name="UserName" column= "Name" type="String" length="40"/>
    <property name="Password" type="String" length="20"/>
    <property name="EmailAddress" type="String" length="40"/>
    <property name="LastLogon" type="DateTime"/>
  </class>
</hibernate-mapping>

讓我們來看看這個文件中讓我們感興趣的某些行。第一個有趣的標簽是class。這里我們將映射類型名稱到我們數據庫中的User表,這里和Hibernate有一點點的不同。你將不得不告訴NHibernate從何處提取對象。

讓我們先跳過id標簽,來討論property標簽。簡要看一下,你將發現NHibernate所要做的工作。name屬性的值正是我們.net 類的屬性,column屬性值將是我們數據庫里的字段。type屬性是可選的(如果你不標明,NHibernate將利用反射進行最佳的推測)。

好了,讓我們回到標簽id,你可以猜測到這個標簽將是映射數據庫表的主鍵,的確如此,id標簽的組成和我們剛才看的property標簽是相似的。我們映射屬性到目標數據庫的字段。
內嵌的generator標簽告訴NHibernate 如何生成主鍵(它將恰當的為你生成主鍵,不管你指定何種類型,但你必須告訴它)。

提示:請將user.hbm.xml的Build Action屬性設置為Embedded Resource。

第四步:為你的數據庫產生一個配置文件

我們至今還沒有告訴NHibernate 去哪里連接數據庫。最直接的辦法是在你的應用程序的配置文件里設置一個NHibernate配置節。這和在Hibernate里使用屬性文件是等價的。如下配置(hibernate.cfg.xml):

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-configuration  xmlns="urn:nhibernate-configuration-2.2" >
  <session-factory name="NHibernate.Test">
    <property name="connection.driver_class">NHibernate.Driver.SQLite20Driver</property>
    <property name="connection.connection_string">
      Data Source=..\output\test.db
    </property>
    <property name="dialect">NHibernate.Dialect.SQLiteDialect</property>
    <property name="show_sql">true</property>
    <mapping assembly="NHibernate.Domain" />
  </session-factory>
</hibernate-configuration>

上面的例子里用了sqlite驅動,在本地連接名稱為test的數據庫,記得引用System.Data.SQLite.dll,否則運行時會報錯。這里還有其他屬性你需要調整來確定如何讓NHibernate來訪問數據庫。再次說明,你可以在文檔里獲取更多信息。

請注意以上的配置里並沒有涉及到log4net的配置信息。NHibernate使用log4net來記錄內部發生的一切。在一個應用程序產品里,在你特定環境里,我推薦配置log4net,並為NHibernate設置一定的日志級別。

第五步:開始展現NHibernate的魔力

所有艱苦的工作已經完成。你將有以下內容
User.cs ----你需要持久化的C#類
User.hbm.xml ----你的NHibernate映射文件
hibernate.cfg.xml ----對數據庫連接的配置信息(如果你願意,你可以在代碼中實現)。
你的數據庫里有一張User表。

現在可以在你的代碼中恰當簡潔的使用NHibernate。
為了讓你更清晰,我們來看一些代碼。

首先創建一個數據庫連接類(NHibernateHelper.cs):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NHibernate.Cfg;

namespace NHibernate.DataPortal
{
    class NHibernateHelper
    {
        private ISessionFactory sessionFactory;

        public NHibernateHelper()
        {
            sessionFactory = GetSessionFactory();
        }

        private ISessionFactory GetSessionFactory()
        {
            return (new Configuration()).Configure().BuildSessionFactory();
        }

        public ISession GetSession()
        {
            return sessionFactory.OpenSession();
        }
    }
}

NHibernate在建樹數據庫連接之前,須要讀取配置文件,然后創建會話(ISession)。在會話中完成各類對數據庫的操縱。

然后建立一個數據庫操作類(UserDal.cs):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NHibernate.Domain;

namespace NHibernate.DataPortal
{
    public class UserDal
    {   
        private NHibernateHelper nhibernateHelper = new NHibernateHelper();

        protected ISession Session { get; set; }

        public UserDal()
        {
            this.Session = nhibernateHelper.GetSession();
        }

        public UserDal(ISession session)
        {
            this.Session = session;
        }

        public void AddUser(User user)
        {
            var aa = Session.Save(user);
            Session.Flush();
        }

        public void DeleteUser(User user)
        {
            Session.Delete(user);
            Session.Flush();
        }

        public void UpdateUser(User user)
        {
            Session.Update(user);
            Session.Flush();
        }

        public IList<User> GetUsers()
        {
            return Session.QueryOver<User>().List();
        }
    }
}

第六步:效果測試

新建一個wpf app界面:

數據庫交互:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using NHibernate.DataPortal;
using NHibernate.Domain;

namespace TestApp
{
    /// <summary>
    /// MainWindow.xaml 的交互邏輯
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private UserDal ud = new UserDal();

        private void button1_Click(object sender, RoutedEventArgs e)
        {
            //Add();
            //Delete();
            //Update();
            Select();
        }

        private void Add()
        {
            User user = new User() { UserName = "Jame", Password = "123456", EmailAddress = "abc@163.com", LastLogon = DateTime.Now };
            ud.AddUser(user);
        }

        private void Delete()
        {
            User user = new User() { Id = 3 };
            ud.DeleteUser(user);
        }

        private void Update()
        {
            User user = new User() { Id = 1, UserName = "Jame1", Password = "1234561", EmailAddress = "abc1@163.com", LastLogon = DateTime.Now };
            ud.UpdateUser(user);
        }

        private void Select()
        {
            IList<User> list = ud.GetUsers();
            listView1.ItemsSource = list;
        }
    }
}

 測試結果:

 

親!真心不錯吧!

 

本文源碼:http://files.cnblogs.com/yuanli/MyNHibernate.zip


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM