[NHibernate] 入門實例 NHibernate 3.3 GA + VS2010 +MySQL

題外話: 中國的技術論壇要趕上stackoverflow的水平,至少還需35年。中國程序員筆者的特點是:太浮躁,太容易下總結,太自得其樂,雖說寫的是爲了讓別人更好的看,卻也演變成了一種“你看,我懂這麼多”的長篇申明——要的就是你不懂。這也似乎是中國沒有有名的開源的原因。

當然了,根據馬克思理論,經濟基礎決定上層建築,這也是可以理解的,拿着那點工資,生活節奏那麼快,壓力那麼大,寫免費的文章,爲別人答疑,顯得有點奢侈。


我建議所有基礎教程類的文章,需要做到以下二點:

【1】 給出運行環境,使用的工具列表,以及版本(版本很重要)。(記得很多工具都是WIN/UNIX都有版本的,有些教程啥都不說,新人看到了雲裏霧裏,拿着UNIX在WIN上測)。版本就更加重要了。別說企業版元素,就是各種開源插件,控件,技術包,也都經常更新,多個文件,少個文件,多個配置,少個配置,都是很正常,而恰恰這細微的變化是很關鍵的,影響運行結果的。

【2】 給出最爲簡單的example,不要把自己公司測試的東西,或者手頭的測試子項目原封不動的往上一貼,如果是基礎教程,就要針對一種技術,做個最簡單的例子,其他的衍生,交給讀者自己去挖掘,一個example夾雜的其他代碼越多,調試出錯的可能性也就越大,很大一批止於途中的讀者都是如此。


就NHibernate和NServiceBus兩個開源技術來說,NHibernate的官方教程簡直就是簡直的差。。。亂七八糟。相反NServiceBus可能初出茅廬,爲了推廣,所以基礎教程做的非常清晰,十分易懂。

-----------------------------------------------------------------------------------------分割線---------------------------------------------------------------------------------

就扯到這裏,以上純屬個人意見,持保留態度。下面正題:

【實例內容】把MySQL內的某個數據庫裏的某張表,使用NHibernate結合到.NET項目中。

【使用軟件和版本】 操作系統:WINDOWS 7.       開發IDE:VS 2010, C#   ,ORM工具:NHibernate 3.3GA。 數據庫 MySQL 5

【有效期日】 2014/4/22日寫,僅對NHibernate 3.3GA 有效,今後如果NHibernate升級,不能保證此文仍然有效。 此時網上的中文實例版本,沒有一個是靠譜的。


引用庫列表:(這些庫需要被分別應用到各個項目中)

要使用NHibernate 和MySQL相連,必須要用到以下幾個庫:

【1】NHibernate 提供的 .NET庫文件以及 schema文件(共四個):Iesi.Collections.dll,NHibernate.dll,nhibernate-configuration.xsd 和 nhibernate-mapping.xsd

 注意: 老版本中還需要Castle的相關文件(致使我走了很多彎路),該版本中是不需要的。還有說編譯了會自動產生Castle,太扯淡了,我可沒發現。

獲得方式: 下載 NHibernate-3.3.3.GA-bin,在文件夾Required_Bins下。

【2】 MySQL 提供的ADO.NET庫文件: MySql.Data.dll,需要注意的是,默認.NET框架中不支持MySQl,需要安裝mysql-connector-net-6.2.4.zip中的mysql.data.msi,然後找到 MySql.Data.dll,這樣有效。


我把上面這些文件都放在了 D:\NetDLL\ 下。

主要步驟:

【1】 在MySQL中創建一個數據庫nhibernatesample,再創建一個表product,創建以下幾個字段:(可以使用GUI軟件來操作,我使用的是MySQL-Fron)

Id int(11) Primary Key
Name varchar(50)
Category varchar(50)

第一個步驟也叫做創建R(關係數據庫)


【2】 在VS中創建一個Class Library 項目TestNH,創建一個Product.cs類用於對應上個步驟中數據庫表product,具體類代碼爲:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NHibernate.Cfg;
using NHibernate;
using TestNH;
using MySql.Data.MySqlClient;

namespace TestNH
{
    public class Product
    {
        public virtual int Id { get; set; }
        public virtual string Name { get; set; }
        public virtual string Category { get; set; }
    }
}
注意,所有字段必須申明爲virtual,這是規定,爲什麼這樣規定的原因比較複雜,這裏不解釋。
第二個步驟也叫做創建 O (內存對象Object)


【3】 在項目TestNH下創建與對象類相關的映射文件Product.hbm.xml

文件名命名格式是: 類名.hbm.xml。

本例中文件內容爲:

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

  <!-- more mapping info here -->
  <class name="Product" table="product">
    <id name="Id" column="Id">
      <generator class="assigned" />
    </id>
    <property name="Name" column="Name" type="String" length="50" />
    <property name="Category" column="Category"  type="String" length="50" />
  </class>
</hibernate-mapping>
注意,這個文件創建號後默認是content文件,爲了讓它在編譯時被讀取,要把它的屬性中的Build Action 設置爲 Embedded Resource。

【可選】雙擊這個文件名,把schemas屬性設置爲:“D:\NetDLL\nhibernate-mapping.xsd” ,注意前面的目錄名根據自己的存放位置自行修改。(PS,我沒有設置,運行也能成功)。各個帖子都這麼說,我先不妄下結論。

上述配置中,TestNH 是項目名,assembly在C#編程範疇裏一般就是指一個項目project。下面的字段一看就懂,不解釋了。


第三個步驟是創建M(Mapping文件),上述三個就完成了 ORM 三個元素的創建。下面要做的就是讓他們整合起來,編譯到我們的項目裏。


【4】編寫整合配置文件hibernate.cfg.xml,這裏有三種方式:類.cs方式,程序配置app.config方式,以及NHibernate配置文件hibernate.cfg.xml方式。這裏我們使用最後一種,也是最爲建議的一種。

在TestNH下創建該文件,文件內容爲:

<?xml version="1.0" encoding="utf-8" ?>

  <hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
    <session-factory>
      <property name="hbm2ddl.keywords">none</property>
      <property name="connection.provider">
        NHibernate.Connection.DriverConnectionProvider
      </property>
      <property name="dialect">NHibernate.Dialect.MySQL5Dialect</property>
      <property name="query.substitutions">hqlFunction=SQLFUNC</property>
      <property name="connection.driver_class">
        NHibernate.Driver.MySqlDataDriver
      </property>
      <property name="connection.connection_string">
        Data Source=localhost;Database=nhibernatesample;User Id=root;Password=123456
      </property>
      <property name="show_sql">false</property>
      <mapping assembly="TestNH" />
    </session-factory>
  </hibernate-configuration>
其中
<property name="hbm2ddl.keywords">none</property>
這句話非常重要,不然最後會把“ReservedWords does not belong to ...” 錯誤。其他字段字面翻譯。注意connection_string 裏需要換成自己的配置。

注意,這個文件的文件屬性中的copy to output directory 屬性,設置爲 copy always。另外,這是告訴程序,每次都要更新這個文件,防止這個文件改了,發佈的時候使用的還是老的配置文件。不僅如此,有時候也不能全信VS2010,過程中如果修改了配置文件,最好是clean 後重新編譯運行。

【可選】最好也雙擊這個文件名,把schemas屬性設置爲:“D:\NetDLL\nhibernate-configuration.xsd” ,注意前面的目錄名根據自己的存放位置自行修改(PS,我沒有設置,運行也能成功)。各個帖子都這麼說,我先不妄下結論。


【5】編寫測試project,

隨便添加個windows application project,如TestCase,別忘了引用上面提到的那些庫文件,然後添加個按鈕,按鈕事件代碼爲:(貼上整個類的代碼)

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using TestNH;
using MySql.Data.MySqlClient;
using NHibernate;
using NHibernate.Cfg;
using NHibernate.Dialect;
using NHibernate.Driver;
using NHibernate.Mapping.ByCode;

namespace TestCase
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            
        }

        private void button1_Click(object sender, EventArgs e)
        {
            Configuration cfg = new Configuration().Configure("hibernate.cfg.xml");
            ISessionFactory factory = cfg.BuildSessionFactory();
            ISession session = factory.OpenSession();
            ITransaction transaction = session.BeginTransaction();
            Product newUser = new Product();
            newUser.Id = 3;
            newUser.Name = "Joseph Cool";
            newUser.Category = "abc123";

            // Tell NHibernate that this object should be saved
            session.Save(newUser);

            // commit all of the changes to the DB and close the ISession
            transaction.Commit();
            session.Close();

            MessageBox.Show("OK!");
        }
    }
}

這裏的調用方式是:

 Configuration cfg = new Configuration().Configure("hibernate.cfg.xml");
網上的各種奇葩調用方式很多(經測試,問題很多),這裏調用方式我沒測試,但是肯定可以用於3.3GA版本。

這句話是告訴編譯器,我將使用這個配置文件。

網上的寫法是:

 Configuration cfg = new Configuration();

說是這樣也會自動尋找這個文件,雖然我沒測試成功。 而且這種寫法也十分的不友好。


F5 運行程序把,不會有錯了。






發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章