上学的时候没有怎么学习.net, 没想到自己找的第一份工作(实习),居然是做.net开发。快要开始实习的时候,公司的人告诉我让我看一下NHibernate和windows 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),1,LockMode)。
(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.2和1.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. 官方网站