现在的位置: 首页 > 综合 > 正文

Nhiberate 笔记

2013年08月15日 ⁄ 综合 ⁄ 共 2048字 ⁄ 字号 评论关闭
文章目录

介绍

新项目用了Nhiberate 来操作数据库。虽然一开始选用的时候觉得会提供工作效率,当实际上选用第三方库有可能会遇到一些问题的,解决这些问题花的时间未必见得比缩短的时间多。不过NHiberate还是很有用的, 顺便把心得记一下,希望对后来人也有帮助

 

资料

配置Hibernate.cfg.xml 和 映射文件xml 就不说了。网上有很多

 

分享

SessionFactory, ISession, ITransaction 

Nhibernate 的ISession不是线程安全的,多个线程同时用一个会出异常。SessionFactory必须是单例,因为这个东西会占20几M的内存,初始化也很慢。一般使用一个Helper类让SessionFactory成为单例。

 

使用ISession 的时候最好使用using 让它的生存期尽可能短,不要让它像静态对象那样一直在那里。对此我有血的教训。原因如下:

 

1. 不关闭ISession会产生内存泄漏。 一直很纳闷为什么越运行越慢,难道垃圾回收器还有不工作的时候? 后来才知道是ISession 没有关闭导致NHiberate没有清空和session关联的对象信息。

 

2. ISession 和 transaction有密切的关系, 当你想用transaction的时候,最好新open出一个ISession 然后在这个session上BeginTransaction 或者 using transactionscope (System.Data里面的),否则会有问题。

 

而且注意在用transaction的时候不要直接open出session然后直接关闭了事, 最好用using() 把session括起来或者 dispose掉,否则下次再begintransaction的时候可能会出错。

还有不要试图对persist对象进行使用 session进行进一步封装,除非你保证在外层绝不用到Nhibernate ,因为你在外层打开了session,在里面又打开了session,当你试图使用transaction的时候这一切会成为噩梦。

 

 

Nhibernate 的性能问题

Nhibernate的性能并不慢,有句话比较经典“programmer is more expansive than machines”。

加载映射文件的问题

文档上说只要把xml属性改成Embeded就好,但是有时候总是加载不上。后来检查发现和当前调用者编译成的形式有关系。如果编成exe的话,就不用手动加载,(即使是被其他引用也不用手动加载),如果xml已经是嵌入资源,在手动加载一遍会出错;如果是编成dll的话,就必须手动加载,编成嵌入资源也不行.

 

Select TOP 问题

 

对象状态不一致问题

遇到过一个对象的状态和数据库不一致的问题,如:

 

出现这种问题是因为NH认为所有的对数据库操作都是通过持久化对象来做的,所以在外部改变了数据库字段时就无法及时反应到持久化对象里。关闭了Lazy就可以避免这个问题。

 

多对多的问题

多对多需要另外一张表,

 

这里面有人说 Set 可以用 IList 还有个什么,但是也有人说必须用Iesi.Collections 中的结构; 我没试过IList之类,不过想Nhibernate里面 Iesi 库这么大,想必还是有点名堂的, 用Iesi.Collections.ISet 实验是可以的。

 

session异常

当一个session中产生数据库操作异常之后,这个session里面所有的对象都无法进行数据库 操作了。这也是让session生存的时间尽可能短的原因。

 

一山不容二虎

一个session里面是允许 两个同类持久化对象拥有同一ID 的,意味着你要小心对象的生存,不要让他们在一个session里面两个同时存在。当你返回一个对象id,希望在别处load它的时候,你可以用session.Evict,在session里面除掉这个对象。

 

 

【上篇】
【下篇】

抱歉!评论已关闭.