1. 程式人生 > >C#連線Mysql資料庫NHibernate

C#連線Mysql資料庫NHibernate

一、什麼是NHibernate?

    NHibernate是一個面向.NET環境的物件/關係資料庫對映工具。物件/關係資料庫對映(object/relational mapping,ORM)這個術語表示一種技術,用來把物件模型表示的物件對映到基於SQL的關係模型資料結構中去。

二、實戰說明

    1.上官網下載全新版本的NHibernate壓縮包,就是那個Download Noew NHX.x-x.點選後下載,然後解壓到一個沒有中文的目錄下(防止出現因中文路徑導致的錯誤),進入 Required_Bins資料夾,找到NHibernate.dll,這個就是我們要引入的程式集。

    2.開啟VS,建立工程,選擇Visual C#,控制檯應用程式,解決方案名稱:NHibernateMySql,名稱:ConnectMysql(自己隨意起就OK了)

    3.保證啟動Mysql,ctrl+alt+.按出任務管理提-點選服務選單,看到有MySQL什麼的正在啟動就OK。若沒有百度一下^_^

    4.建立資料庫test,表User,表中有【主鍵:Id(int),Username(varchar)】,Password(varchar)。

    5.右擊工程,點選屬性,修改工程的預設名稱空間為:NHMsql,程式集名稱

    6.建立Model資料夾,Mappings資料夾

    5. 使用NHibernate完成類與資料庫的對映關係流程如下:

        1) 配置NHibernate對映資料庫

        2) 載入對映檔案

        3) 建立會話工廠

        4) 開啟會話

        5) 使用會話進行業務操作

    6.程式碼

        6.1 配置NHibernate對映資料庫

            首先,新建NHibernate配置檔案hibernate.cfg.xml (XML檔案),命名一定要寫hibernate.cfg.xml

            hibernate.cfg.xml內容:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
  <session-factory>
    <property name="connection.provider">NHibernate.Connection.DriverConnectionProvider</property>
    <property name="dialect">NHibernate.Dialect.MySQL5Dialect</property><!--設定MySql版本-->
    <property name="connection.driver_class">NHibernate.Driver.MySqlDataDriver</property><!--使用MySql資料庫-->
    <property name="connection.connection_string">Server=localhost;Database=test;User ID=root;Password=root;</property><!--資料庫在本地,用Root使用者連test資料庫-->
    
    <property name="show_sql">true</property>
  </session-factory>
</hibernate-configuration>

            注意:MySql版本要設定好,如何檢視自己的MySql版本?百度^_^. 還有,如果是MySql 5.X.x的,那麼就是MySql5版本,如果是其他版本,只需要把那個5修改即可,我上面的是5號版本。 

            而且該檔案的屬性-高階,必須設定成:始終複製到輸出目錄

        6.2 在Model資料夾下,新建User類     

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace NHMysql.Model
{
    class User
    {
        public virtual int Id { get; set; }
        public virtual string Username { get; set; }
        public virtual string Password { get; set; }
    }
}

        6.3 配置User對映檔案 (User.hbm.xml) (對字尾有要求,即字尾一定要寫成.hbm.xml)  放入Mappings資料夾

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
                   assembly="NHMysql"
                   namespace="NHMysql.Model">

	<class name="User" table="User">
		<id name="Id" column="Id" type="Int32">
			<generator class="native"></generator>
		</id>
		<property name="Username" column="Username" type="String"/>
		<property name="Password" column="Password" type="String"/>	
	</class>
</hibernate-mapping>

注意:該檔案必須修改屬性-高階:嵌入的資源

解釋說明:

                assembly="MHMysql" 指定程式集是MHMysql,這個程式集下的namespace="NHMysql.Model"名稱空間,因為這個程式集下的名稱空間有我們對映的類,也就是User類。

<class name="User" table="User">

name指定了User類,table指定User類對應的是test資料庫中的User表

這樣,User類 與 User表就產生了一個對映關係。

下面的<id>、<property>都是設定類 與 表的 屬性對映關係,name指定類的屬性(Id,Username,Password),column指定表的欄位(列)(Id,Username,Password)

而放在<id>內是表明那個屬性是主鍵對映關係,其他都是普通的屬性對映。

(這裡,有個錯誤沒補全,那就是Username也是主鍵,而這裡沒放在<id> 中,各位可以試試改為<id>會不會出錯。)

        6.4 建立會話工廠

            因為我們的程式需要不斷地使用[會話]來進行業務操作,所以我們可以建立一個類專門處理[會話工廠]的建立以及開啟[會話],便於我們獲取會話物件,且減少程式碼冗餘。

            新建一個類NHibernateHelper,內容如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using NHibernate;
using NHibernate.Cfg;
namespace NHMysql
{
    class NHibernateHelper
    {
        private static ISessionFactory _sessionFactory;//這就是會話工廠

        private static ISessionFactory SessionFactory
        {
            get {
                if (_sessionFactory == null)
                {   //新建一個Configuration物件,用它來配置我們的對映環境,最終構建出一個會話工廠!
                    var configuration = new Configuration();
                    //配置對映資料庫 即這個方法必定去解析名為:hibernate.cfg.xml的檔案,該檔案屬性高階:始終複製到輸出目錄(這一步必須做,不然解析失敗)
                    configuration.Configure();
                    //載入NHMysql程式集的對映檔案 這些對映檔案即 .hbm.xml字尾的,必須嵌入到程式集,即設定 屬性->高階:嵌入的資源                    
                    configuration.AddAssembly("NHMysql");
                    //Session工廠,這個工廠就是處理由Configure配置的資料庫操作,載入對映檔案是為了能夠將資料庫上的表對映到相應的Model檔案下的類
                    _sessionFactory = configuration.BuildSessionFactory();
                }
                return _sessionFactory;
            }

        }
        //開啟會話
        public static ISession OpenSession()
        {
            //返回一個Session會話物件,由外部關閉
            return SessionFactory.OpenSession();
        }
    }
}

        6.5 建立Manager管理類

        因為我們業務操作的基本操作都需要增、刪、改、查,所以我們新建一個介面interface,名為IBaseManager,它帶一個泛型T,我們的所有Manager管理類都會繼承它,而泛型T就是用於區分不同的管理類的。

IBaseManager介面:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace NHMysql.Manager
{
    interface IBaseManager<T>
    {
        void Add(T user);
        void Update(T user);
        void Remove(T user);
        T GetById(int id);
        T GetByUsername(string username);
        ICollection<T> GetAllUser();
        bool VerifyUser(string username, string password);
    }
}

新建UserManager類:   

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using NHibernate;
using NHibernate.Criterion;
using Sikiedu.Model;

namespace NHMysql.Manager
{
    class UserManager:IBaseManager<User>
    {
        #region IUserManager 成員

        public void Add(Model.User user)
        {                        
            //using ()裡面建立的物件會在using結構體中產生作用,並且在using結構體結束時候釋放session資源
            using (ISession session = NHibernateHelper.OpenSession())//開啟會話
            {
                //同樣,建立一個業務 也需要使用using 因為業務也要釋放
                using (ITransaction transaction = session.BeginTransaction())
                {
                    session.Save(user);//儲存這個user進入資料庫test的User表,為什麼用session.Save 程式就會自動把這個user放入對應的表呢?那就是我們之前做的對映環境的作用啦.
                    transaction.Commit();//執行這一步,真正地執行儲存操作
                }
            }
        }

        public void Update(Model.User user)
        {
            using (ISession session = NHibernateHelper.OpenSession())
            {
                using (ITransaction transaction = session.BeginTransaction())
                {
                    session.Update(user);
                    transaction.Commit();
                }
            }
        }

        public void Remove(Model.User user)
        {
            using (ISession session = NHibernateHelper.OpenSession())
            {
                using (ITransaction transaction = session.BeginTransaction())
                {
                    session.Delete(user);
                    transaction.Commit();
                }
            }
        }

        public Model.User GetById(int id)
        {
            using (ISession session = NHibernateHelper.OpenSession())
            {
                using (ITransaction transaction = session.BeginTransaction())
                {
                    User user = session.Get<User>(id);//這種獲取方式最簡單,通過主鍵Id獲取User
                    transaction.Commit();
                    return user;
                }
            }
        }

        public Model.User GetByUsername(string username)
        {
            using (ISession session = NHibernateHelper.OpenSession())
            {            
                //CreateCriteria(typeof(User))是代表從User表查詢
                //Add(Restrictions.Eq("Username", username)),Add相當於加條件,條件內容是Username==username,(Eq)是相等條件
                //UniqueResult<User>()是查詢出的內容封裝為User物件
                return session.CreateCriteria(typeof (User)).Add(Restrictions.Eq("Username", username)).UniqueResult<User>();
                //關於Restrictions的使用http://nhibernate.info/doc/nh/en/index.html,搜Restrictions可看到相關例子
            }
        }

        //注意返回值是ICollection<User>
        public ICollection<Model.User> GetAllUser()
        {
            using (ISession session = NHibernateHelper.OpenSession())
            {
                return session.CreateCriteria(typeof (User)).List<User>();//查詢User表所有資料,返回一個User集合
            }
        }

        #endregion

        #region IUserManager 成員

        //驗證使用者存在與否
        public bool VerifyUser(string username, string password)
        {
            using (ISession session = NHibernateHelper.OpenSession())
            {        
                User user = session.CreateCriteria(typeof(User))
                    .Add(Restrictions.Eq("Username", username))
                    .Add(Restrictions.Eq("Password",password))  //這樣相當於where Username==username&&Password==password,也有另一種寫法,用And來把它們2個相同條件封裝起來
                    .UniqueResult<User>();

                if(user==null)
                 return false;

                return true;
            }
        }

        #endregion
    }
}

Program.cs程式碼:

    測試方法: IBaseManager<User> userManager = new UserManager(); 然後用這個userManager裡面的方法對test資料庫User表進行增、刪、改、查