ORM利器:NHibernate(三)五部曲+簡單對象CRUD+HQL,ormcrud

來源:互聯網
上載者:User

ORM利器:NHibernate(三)五部曲+簡單對象CRUD+HQL,ormcrud

前面的兩篇文章中,我們對NHibernate已經做了大致瞭解

    《ORM利器:NHibernate(一)簡介》Nhibernate的作用:解決了對象和資料庫的轉化問題

    《ORM利器:NHibernate(二)使用CodeSmith快速產生對應檔和映射類 》利用CodeSmith由表匯出映射類(就是通常所說的Entity)和對應檔(告訴你表和對象之間是如何建立一一對應的關係的)。


接下來將會對NHibernate的使用做Demo解析,分為五部曲:

  1. 建立表。若要把對象轉換為資料庫中的表,自然要有對一個的表。因此,首先要在資料庫中建立把.Net類持久化的對應表。
  2. 建立類。建立需要被持久化的.Net類.對象。
  3. 建立對應檔。 描述對象和庫之間的關係,告訴NH怎樣持久化這些類的屬性.
  4. 建立NH的設定檔,以告訴NH怎樣串連資料庫,以何種方式串連不同種類的資料庫。
  5. 使用NH提供的API。維護對象和庫之間的關係,對對象的CRUD和對資料庫的DML.

步驟詳情: 第一部:建立表(步驟很簡單,這裡不做解釋)
第二部:建立類+第三部:建立對應檔(本Demo利用CodeSmith自動產生,詳細請參見《ORM利器:NHibernate(二)使用CodeSmith快速產生對應檔和映射類 》)
第四部:建立NH設定檔        主要用於串連資料庫:驅動的提供者、驅動的位置、資料庫的身分識別驗證資訊等,和我們曾經寫過的資料庫連接語句無意,只不過放在了設定檔中而已。而且NH採用代理工廠,針對不同的資料庫產品進行生產,提供了更好的靈活性,如果你需要把SQLServer資料庫,更改為Oracle資料庫,只需要更改相應的配置資訊就可以。
<?xml version="1.0" encoding="utf-8" ?><configuration>  <configSession>    <section name="hibernate-configuration" type="NHibernate.Cfg.ConfigurationSectionHandler,NHibernate" requireParmission="false"/>  </configSession>  <hibernate-configuration  xmlns="urn:nhibernate-configuration-2.2" >    <!--Session工廠,使用者層級的對象-->    <session-factory name="NHibernate.Test">      <!--驅動是由誰提供的-->      <property name="connection.provider">NHibernate.Connection.ConnectionProvider,NHibernate</property>            <!--驅動類的位置-->      <property name="connection.driver_class">NHibernate.Driver.SqlClientDriver</property>           <!--身分識別驗證登陸-->      <property name="connection.connection_string">Server=(local);initial catalog=NHibernate;Integrated Security=SSPI</property>      <property name="dialect">NHibernate.Dialect.MsSql2008Dialect</property>      <!--是否顯示sql語句-->      <property name="show_sql">False</property>            <!--代理工廠,針對不同的資料庫產品進行生產-->      <property name="proxyfactory.factory_class">NHibernate.ByteCode.Linfu.ProcxyFactoryFactory,NHibernate.ByteCode.Linfu</property>          </session-factory>  </hibernate-configuration></configuration>
    如果你覺得設定檔很複雜、記不住,也沒有關係。NH為我們提供了很多設定檔的模板以供參考,這裡我們採用SQLServer,因此可以參照:Configuration_Templates—MSSQL.cfg.xml

第五部:使用NH提供的API。維護對象和庫之間的關係,對對象的CRUD和對資料庫的DML

1、目錄結構如下:

1)建立類庫Test:

    用於存放所有的對象和.NET對應檔(如此處的Person.cs對象,Person.hbm.xml對應檔),為了讓NHibernate能夠找到所有的對應檔,必須設定為“嵌入資源”,產生Test.dll檔案備用。

2)添加引用:

2、添加表單Form1,:

3、表單Form1中的代碼如下所示:

    首先,通過config讀取設定檔,讀取所有對應檔,載入程式集(必須是嵌入資源)
    其次,通過SessionFactory建立session工廠,負責持久化的串連以及OR映射(該對象的開銷比較大,一般建議用單例模式實現)
    然後,通過session建立一個可以用於使用者層級的操作對象。
    開啟事務對象trans = session.BeginTransaction();


    上面的思路和我們曾經使用過的SQLServer是一個道理。接下來看一下不同點:

    以前D層和資料庫打交道的時候,我們通常使用sql語句,而後直接對資料庫進行操作。而在NH中所有的操作(增刪改查)全都是針對“對象”而言的,如果想要把對象儲存在資料庫中,就需要先將對象必須轉化為資料庫能識別的sql語句,由於在SessionFactory中已經儲存了所有的OR映射,ISession能根據相應的方言實現sql語句。

    下文的代碼中已經實現了簡單操作對象。主要是通過session的get、save、delete方法來實現。若要實現複雜的查詢不免會比較繁瑣。NHibernate提供了一種強大的查詢語言HQL(Hibernate Query Language),它的文法非常類似於Sql,不同的是只能用於對資料進行查詢操作,不能用於資料增、刪、改。它是完全物件導向的,具備繼承、多態和關聯等特性。

using System;using System.Collections;using System.Collections.Generic;using System.Windows.Forms;using NHibernate;using NHibernate.Cfg;using Test.Model;using System.Linq;namespace WinFormTest{    public partial class Form1 : Form    {        //建立session        ISession session = null;        //建立session工廠        ISessionFactory factory = null;        //建立事務        ITransaction trans = null;        public Form1()        {            InitializeComponent();        }        private void Form1_Load(object sender, EventArgs e)        {            //讀取設定檔            //讀取所有對應檔,載入程式集,必須是嵌入資源            Configuration config = new Configuration().AddAssembly("Test.Model");            //建立session工廠,負責持久化的串連以及OR映射,該對象的開銷比較大,一般建議用單例模式實現            factory = config.BuildSessionFactory();            //建立一個可以用於使用者層級的操作對象            session = factory.OpenSession();        }        //添加使用者        private void btnAdd_Click(object sender, EventArgs e)        {            //開啟事務對象            trans = session.BeginTransaction();            //使用NHibernate現有API            //體驗過程            try            {                //對象的執行個體化方式                Person p = new Person();                p.Name = this.txtName.Text;                //把對象儲存在資料庫中                //將對象必須轉化為資料庫能識別的sql語句                //由於在SessionFactory中已經儲存了所有的OR映射                //ISession能根據相應的方言實現sql語句                session.Save(p);                trans.Commit();            }            catch (Exception)            {                //出錯後,交易回復                trans.Rollback();            }        }        //查詢使用者        private void btnFind_Click(object sender, EventArgs e)        {            //trans = session.BeginTransaction();            //尋找ID編號為2的人            //2-->ID屬性——OR——>SQL的Where語句            Person p = (Person)session.Get(typeof(Person), int.Parse(this.txtID.Text));            //Console.WriteLine(p.ToString());            this.txtName.Text = p.Name;        }        //刪除使用者        private void btnDelete_Click(object sender, EventArgs e)        {            try            {                //開啟事務                trans = session.BeginTransaction();                //根據提供的ID尋找該對象                Person p = (Person)session.Get(typeof(Person), int.Parse(this.txtID.Text));                //對象刪除                session.Delete(p);                trans.Commit();            }            catch (Exception)            {                trans.Rollback();            }        }        //更新使用者        private void btnUp_Click(object sender, EventArgs e)        {            try            {                //開啟事務                trans = session.BeginTransaction();                //根據提供的ID尋找該對象                Person p = (Person)session.Get(typeof(Person), int.Parse(this.txtID.Text));                //修改對象屬性                p.Name = this.txtName.Text;                session.Update(p);                trans.Commit();            }            catch (Exception)            {                trans.Rollback();            }        }        //IQuery介面,是針對物件查詢        private void btnHQL_Click(object sender, EventArgs e)        {            //HQL體驗——HQL是針對對象的查詢語言            //查詢所有人的資訊            //IQuery query = session.CreateQuery("from Person");            //IList<Person> persons = query.List<Person>();            //persons.p1();            //查詢編號為2的人的資訊            //IQuery query = session.CreateQuery("from Person where Id=3");            //query.List<Person>().p1();            //查詢名字中有字母a的人            //session.CreateQuery("from Person where Name like '%a%'").List<Person>().p1();            //session.CreateQuery("from Person where t_Name like '%a%'").List<Person>().p1();            //session.CreateQuery("from Person where name like '%a%'").List<Person>().p1();//錯誤            //尋找全部            //session.CreateQuery("select p from Person p").List<Person>().p1();            //session.CreateQuery("select * from Person ").List<Person>().p1();//錯誤,沒有*            //尋找編號大於5的人的資訊            //session.CreateQuery("from Person p where p.Id>5 ").List<Person>().p1();            //彙總函式的使用--統計人數            //session.CreateQuery("select count(p.Id) from Person p ").List().p2();            //傳參1            //IQuery query = session.CreateQuery("from Person p where p.Id>?");            //query.SetParameter(0,7);            //query.List<Person>().p1();            //傳參2            //IQuery query = session.CreateQuery("from Person p where p.Id>:id");            //query.SetParameter("id", 7);            //query.List<Person>().p1();            //插入資料——Insert/Update/Delete不建議在HQL裡面操作            //IQuery query = session.CreateQuery("insert into t_Person(t_Name) values(?)");            //query.SetParameter(0,"kkk");            //query.ExecuteUpdate();            //查詢指定範圍的資料——查詢第3-7條記錄            IQuery query = session.CreateQuery("from Person");            query.List<Person>().Skip<Person>(3).Take<Person>(5).ToList<Person>(); ;            //用ICriteria來實現該功能可能更方便        }        //對IList<Person>類型資料的輸出,建議用C#3.0的拓展方法來實現        public static class ExtraClass        {            public static void p1(this IList<Person> p)            {                //擷取可枚舉的介面對象                IEnumerator<Person> ie = p.GetEnumerator();                Console.WriteLine("\n-----------------------\n");                //遍曆                while (ie.MoveNext())                {                    Console.WriteLine(ie.Current.ToString());                }                Console.WriteLine("\n-----------------------\n");            }            public static void p2(this IList p)            {                IEnumerator ie = p.GetEnumerator();                Console.WriteLine("\n-----------------------\n");                while (ie.MoveNext())                {                    Console.WriteLine(ie.Current.ToString());                }                Console.WriteLine("\n-----------------------\n");            }        }    }}

總結:對於NHibernate的操作,本文通過五部曲進行細緻的講解:1、建立表;2、建立類;3、建立對應檔(表和類是如何對應的);4、NH設定檔(串連資料庫);5、利用API操作。

    其中,2、3 我們採用CodeSmith自動產生映射類和對應檔;4就是我們曾做的串連資料庫操作;5通過NHibernate提供的API,通過對對象操作,已達到操作資料庫的目的,避免了冗長複雜的sql語句。

    希望大家重點理解建立的過程,以及API的使用。





相關文章

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.