NHibernate学习笔记

上学的时候没有怎么学习.net 没想到自己找的第一份工作(实习),居然是做.net开发。快要开始实习的时候,公司的人告诉我让我看一下NHibernatewindows communication service(WCF) 实习都快3个月,早就该总结一下了。

我学习NHibernate主要分三步,把大象装冰箱3不就够了,我想学习这个3步也足够了:

1. 在网上搜资料然后看

在这期间我觉得最好的就是 ”NHibernate Step by Step(教程)“, 很适合初学者。因为我有Hibernate的基础,所以比较能够理解。怎么样进行NHibernate配置就不说,用工具基本可以搞定,自己在写一些 Session管理的代码就好了。值得一体的是model.hbm.xml 文件,这个文件属性中 Build Action要设置成Embedded Resource。不然会抛出一个unknown实体类的异常。很容易忘记的。
对于数据库的操作无非就是查找,插入,更新和删除。
查找:

(1) session. Get(typeof(Person),1)方法得到一个Person类的对样,这个方法有一个重载的方法ession. Get(typeof(Person),1LockMode)

(2) session.Load  方法,它也重载了带有LockMode参数的方法。 LockMode的用途下面说。(1)(2)的区别是 Get在找不到对象时会返回一个null引用,而Load则会抛出一个ObjectNotFoundException,所以,不应该用Load来判断记录是否存在。

(3)使用session.query 就是自己写HQL语句,可以很好的支持二级查询
(4)
使用 Criteria Query 基本结构是:

ICriteria criteria = session.CreateCriteria(typeof(Person));//添加表达式
      criteria.Add(Expression.Eq("Name","Jackie Chan"));
      IList list = criteria.List();
其中Add是添加的查询条件,EXpression有很多表达式。criteria.List()是返回结果的形式也有很多选择。

插入和删除:

一般都是用session.Save() session.Delete()

更新:

都是先用Load方法得到对象的entity。然后再Update或者SaveOrUpdate 注意,用transaction的时候完成前面的步骤后要commit(),不用transaction的时候要flush()

2. 看官网上面的原文文档

可以在这里下载。http://www.hibernate.org/5.html#A26 1.21.02两个版本的。

这里要说的有两点:

(1)前面提到的LockMode,这个在中文Chm里面没有人翻译,原文是这样的。

The LockMode class defines the different lock levels that may be acquired by NHibernate. A lock is obtained by the following mechanisms:

LockMode.Write is acquired automatically when NHibernate updates or inserts a row.

LockMode.Upgrade may be acquired upon explicit user request using SELECT ... FOR UPDATE on databases which support that syntax.

LockMode.UpgradeNoWait may be acquired upon explicit user request using a SELECT ... FOR UPDATE NOWAIT under Oracle.

LockMode.Read is acquired automatically when NHibernate reads data under Repeatable Read or Serializable isolation level. May be re-acquired by explicit user request.

LockMode.None represents the absence of a lock. All objects switch to this lock mode at the end of an ITransaction. Objects associated with the session via a call to Update() or SaveOrUpdate() also start out in this lock mode.

 

我觉的这里要常用的就是要注意,LockMode.Upgrade LockMode.UpgradeNoWait。当你先load一个entity,然后在更新他的时候,load的时候要用LockMode.Upgrade

(2) NHibernate.Caches缓存

NHibernate.Caches NHibernate 的附加软件,它是Kevin Williams (aka k-dub)贡献的.缓存是一个保存实体的地点(在首次加载时);一旦进入缓存,能够取得它们,而无需(再次)查询的后台的存储(数据库)。这意味着它们能更快的加载(或重新加载)。

NHibernate session有一个内部的(一级)缓存,存放着它的实体。这些缓存没有共享,因此session被销毁时它的缓存也被销毁了。NHibernate提供了二级缓存系统;他在SessionFactory级别工作。因此它被同一个SessionFactory产生的session共享。

使用每个请求(request)一个session模式,很多个Session可以并发的访问同一个实体,而不用每次都访问数据库,因此性能获得了提升。

这里的二级缓存主要有两类:

NHibernate.Caches.Prevalence使得使用底层的 Bamboo.Prevalence实现作为缓存提供者成为可能。打开文件Bamboo.Prevalence.license.txt可以看到它的许可信息,你也可以访问它的站点

NHibernate.Caches.SysCache使得使用底层的System.Web.Caching.Cache实现作为缓存提供者成为可能。这意味着你可以依赖ASP.NET的缓存特性来理解它是怎么工作的。要得到更多的信息,可以阅读Caching Application Data(在NSDN上)。

如何使用?

这里是在NHibernate中启用二级缓存的步骤:

选择需要使用的缓存提供者并且拷贝它的程序集到你的程序集路径(NHibernate.Caches.Prevalence.dll 或者NHibernate.Caches.SysCache.dll).

为了表明使用哪种缓存提供者,NHibernate配置文件中(可以在YourAssembly.exe.config或者web.config或者.cfg.xml 文件)添加下面的内容:

<add key="hibernate.cache.provider_class" value="XXX" />

<add key="relativeExpiration" value="120" />

"XXX" 可以是 "NHibernate.Caches.Prevalence.PrevalenceCacheProvider, NHibernate.Caches.Prevalence" 或者"NHibernate.Caches.SysCache.SysCacheProvider, NHibernate.Caches.SysCache"

relativeExpiration的值是你希望缓存每个实体的秒数(这里是两分钟)

添加<cache usage="read-write|nonstrict-read-write|read-only"/>(<class>后面)到你需要缓存的实体映射中.它也为集合(bag, list, map, set, ...)提供支持.

小心:缓存不会知道另一个进程存储的实体的变化(尽管配置了缓存数据的过期时间).当缓存被建立在SessionFactory级别,他们会和SessionFactory实例一起被销毁; 所以必须在你需要缓存的时候,保持SessionFactory存在.

 

3.在实践中学习

这里我发现了两个问题

(1)    我发现code smith NHibernate模板 并不是很好用,公司的人推荐我用的是Codus, http://www.adapdev.com/codus/

(2)    做好session的管理,可以把session管理写在一个单独的类里面,写的时候应用泛型。然后在写DAO的时候直接集成就行了,很方便。而且不用担心seesion会有问题。帖一小段代码(如果写的垃圾的话,不要嘲笑我啊,为节约地方注释已经删掉)

HibernateDao

public abstract class HibernateDao<T, IdT> : IDao<T, IdT>

    {

        public T GetById(IdT id, bool shouldLock)

        {

            T entity;

            if (shouldLock)

            {

                entity = (T)NHibernateSession.Load(persitentType, id, LockMode.Upgrade);

            }

            else

            {

                entity = (T)NHibernateSession.Load(persitentType, id);

            }

            return entity;

        }

        public T SaveOrUpdate(T entity)

        {

            NHibernateSession.SaveOrUpdate(entity);

            return entity;

        }

        public void Delete(T entity)

        {

            NHibernateSession.Delete(entity);

        }

        public T Update(T entity)

        {

            NHibernateSession.Update(entity);

            return entity;

        }

        public void CommitChanges()

        {

            if (NHibernateSessionManager.Instance.HasOpenTransaction())

            {

                NHibernateSessionManager.Instance.CommitTransaction();

            }

            else

            {

                NHibernateSessionManager.Instance.GetSession().Flush();

            }

        }

}

NHibernateSessionManager

public sealed class NHibernateSessionManager

    {

        private const string TRANSACTION_KEY = "CONTEXT_TRANSACTION";

        private const string SESSION_KEY = "CONTEXT_SESSION";

        private ISessionFactory sessionFactory;

        #region Thread-safe, lazy Singleton

        public static NHibernateSessionManager Instance

        {

            get

            {

                return Nested.NHibernateSessionManager;

            }

        }       

private NHibernateSessionManager()

        {

            InitSessionFactory();

        }

        private class Nested

        {

            static Nested() { }

            internal static readonly NHibernateSessionManager NHibernateSessionManager =

                new NHibernateSessionManager();

        }

        #endregion

public ISession GetSession()

        {

            return GetSession(null);

        }

        private ISession GetSession(IInterceptor interceptor)

        {

            ISession session = ContextSession;

            if (session == null)

            {

                if (interceptor != null)

                {

                    session = sessionFactory.OpenSession(interceptor);

                }

                else

                {

                    session = sessionFactory.OpenSession();

                }

                ContextSession = session;

            }

            return session;

        }

        public void CloseSession()

        {

            ISession session = ContextSession;

 

            if (session != null && session.IsOpen)

            {

                session.Flush();

                session.Close();

            }

            ContextSession = null;

        }

        public void BeginTransaction()

        {

            ITransaction transaction = ContextTransaction;

            if (transaction == null)

            {

                transaction = GetSession().BeginTransaction();

                ContextTransaction = transaction;

            }

        }

          ……………..

}

 

上面是我学习NHibernate的一个小结,希望对正在学习的和我一样是入门级的人有所帮助啊。

 

参考文献:我都上传到Csdn下载里面了

1.       NHibernate Step by Step(教程).doc http://download.csdn.net/source/764807

2.       NHibernate.Documentation.chm(英文版)和Nhibernate中文版.chmhttp://download.csdn.net/source/764808

3.       官方网站

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值