文章导读:

      我们知道NHibernate源自Java里面的Hibernate,是一个数据持久化构件,它能大大缩减对数据的持久化编程任务,解放生产力。NHibernate 是一个开源软件,可以在 这里 下载最新的版本及相应的源代码。关于NHibernate的使用网上也有很多教程,中文的,E文的都有,有官方的NHibernate Reference,也有网友翻译的中文版指南。这个百度或者Google里面都能找到。

     本系列讨论的主题将围绕NHibernate的设计对NHibernate源代码进行分析,试图通过软件再工程和软件重构来了解它的设计思想。要了解其设计思路,首先要了解NHibernate的使用,它能为我们做哪些事情。关于NHibernate的使用,网上教程也挺多的。李永京的博客园里面有个关于NHibernate使用的教程,我个人觉得写得挺好的,适合新手学习。我把网站给出来:http://www.cnblogs.com/lyj/archive/2008/10/30/1323099.html,大家自己研究吧!

      本系列所有文章所采用的组件,源代码,文档等都是以为基准版本,开发环境为Visual Studio 2010,数据库为Ms Sqlserver 2008.编译时Framework为.net 3.5.

 本文主题:

      本文将讨论NHibernate中的Session建立过程.

阅读对象:

      对NHibernate的使用有一定的了解,并想了解NHibernate源代码及其软件结构的人。

源码下载:

      点击这里下载源码

 

正文:

      我们知道NHibernate使用前先要建一个Session(类似于Adonet编程里面的连接),因为Session是NHibernate来实现(CRUD:Create+Retrieve+Update+Delete)即常说的新增改查的基础。而建Session必须由SessionFactory来打开,通常我们使用的时候,可以这样来获取Session:

using System; using System.Collections.Generic; using System.Text; using NHibernate; using NHibernate.Cfg; /// <summary> /// Session类 /// </summary> public class Session { public static ISession _CurrentSession; public static ISession CurrentSession { get { if (_CurrentSession == null) _CurrentSession = new Session().GetSession(); return _CurrentSession; } } public ISession GetSession() { //创建Session工厂来产生Session,SessionFactory是线程安全的 ISessionFactory _SessionFactory = (new Configuration()).Configure().BuildSessionFactory(); //由SessionFactory来打开一个Session对象 ISession _Session = _SessionFactory.OpenSession(); return _Session; } }   

我们可以把NHibernate源代码项目加到我们使用NHibernate的解决方案项目中来,这样我们可以通过调试的方式跟踪到源代码里面。上面的代码中将会做以下一些事情:

1.new Configuration() => 初化NHibernate的配置,这些配置信息来自于一个新初始化的配置信息工厂(SettingsFactory),见/NHibernate/Cfg/SettingsFactory.cs文件.初始化的时候将完成一些配置字典的的初始化,配置信息映射等工作。

2.Configure() =>Configure()方法将从使用前我们配置好的xml文件hibernate.cfg.xml中读取配置信息。读取<hibernate-configuration>节点下面的信息

3.BuildSessionFactory() =>BuildSessionFactory()方法用来创建Session工厂ISessionFactory。这其中将完成一系列的工作,如

1)配置ProxyFactoryFactory(将xml文件中的proxyfactory.factory_class属性值配置到相应代理工厂环境);

2)编译构建映射 <实体类>.hbm.xml中一对一,一对多,外键,过滤条件;

3)应用实体,集合,过滤条件;

4)校验hibernate.cfg.xml中<property>节点中的属性;

5)将映射保存到NHibernate的设置信息里面.

6)根据上述操作中配置信息(Configure),映射信息(Mapping),设置信息(ISetting)及事件侦听信息(EventListeners),构建SessionFactory.这个具体工作由SessionFactoryImpl来实现(NHibernate.Impl.SessionFactoryImpl.cs).

4._SessionFactory.OpenSession() =>从SessionFactory业打开一个Session,这个由SessionFactoryImpl类中的OpenSession()来调用SessionImpl类来实现。

      Session打开之后,我们就可以用这个Session来干很多事情了.下面的类实现实体的CRUD操作:

using System; using System.Collections.Generic; using System.Text; using NHibernate; /// <summary> /// 实体类,可以作为基类派生,也可以单独使用 /// </summary> /// <typeparam name="T"></typeparam> public class Entity<T> { //获得可用Session public ISession Session { get; set; } public Entity(ISession _Session) { this.Session = _Session; } //取得实体T的信息 public T GetEntity(int ID) { return Session.Get<T>(ID); } //创建一个实体T的实例并保存 public void Create(T t) { Session.Save(t); Session.Flush(); } //根据HQL语句filterString来取得满足条件的T数据集合 public IList<T> Retrieve(string filterString) { return Session.CreateQuery(filterString).List<T>(); } //更新一个实体T的实例并保存 public void Update(T t) { Session.Update(t); Session.Flush(); } //删除一个实体T的实例并保存 public void Delete(T t) { Session.Delete(t); Session.Flush(); } //更新或者新增一个T集合的数据 public void SaveOrUpdate(IList<T> ts) { using (ITransaction tran = Session.BeginTransaction()) //Transaction { try { foreach (var m in ts) Session.SaveOrUpdate(m); Session.Flush(); tran.Commit(); } catch (HibernateException) { tran.Rollback(); throw; } } } }  

使用的时候可以这样来使用:

using System; using System.Collections.Generic; using System.Text; class Program { public static void Main() { try { Entity<Customer> mbr = new Entity<Customer>(Session.CurrentSession); //创建用户 Customer newCustomer = new Customer { UserName = "John", NickName = "J", Birthday = DateTime.Now, Email = "tuohzh03@yahoo.com.cn", IsVip = true, LoginCount = 1, Money = 12.5M, Password = "123", Sex = "男" }; mbr.Create(newCustomer); Console.WriteLine("已经创建了1个用户 {0}", newCustomer.UserName); //查询用户 IList<Customer> users = mbr.Retrieve(" from Customer"); Console.WriteLine("已经读取到了 {0} 个用户信息。", users.Count); //更改用户 newCustomer = users.First(); newCustomer.Email = ""; mbr.Update(newCustomer); Console.WriteLine("已经对 {0} 的电子邮件进行了更改.", newCustomer.UserName); //删除用户 mbr.Delete(newCustomer); Console.WriteLine("已经删除了用户 {0} .", newCustomer.UserName); } catch (Exception ex) { Console.WriteLine("出现错误:" + ex.Message); } Console.ReadKey(); } }   

分析总结:

      Session建立过程中主要完成以下几个方面的事情:

1.生成hibernate.cfg.xml文件中对应的配置信息

2.生成<实体类>.hbm.xml文件中对应的配置信息,设置信息,映射信息,事件侦听信息

3.生成并打开Session实例