Contains 缓存中是否存在SessionFactoryBizCom.GetInstance().GetCurrentSession().Contains(t1)

Evict

临时状态(Transient):当new一个实体对象后,这个对象处于临时状态,即这个对象只是一个保存临时数据的内存

区域,如果没有变量引用这个对象,则会被jre垃圾回收机制回收。这个对象所保存的数据

与数据库没有任何关系,除非通过Session的save或者SaveOrUpdate把临时对象与数据库

关联,并把数据插入或者更新到数据库,这个对象才转换为持久对象。

持久状态(Persistent): 持久化对象的实例在数据库中有对应的记录,并拥有一个持久化表示(ID)。对持久化对

象进行delete操作后,数据库中对应的记录将被删除,那么持久化对象与数据库记录不再

存在对应关系,持久化对象变成临时状态。持久化对象被修改变更后,不会马上同步到数

据库,直到数据库事务提交。在同步之前,持久化对象是脏的(Dirty)。

游离状态(Detached):当Session进行了Close、Clear或者evict后,持久化对象虽然拥有持久化标识符和与数据

库对应记录一致的值,但是因为会话已经消失,对象不在持久化管理之内,所以处于游离

状态(也叫:脱管状态)。游离状态的对象与临时状态对象是十分相似的,只是它还含有

持久化标识。

hibernate session的flushMode的区别

这里面的清理缓存可以理解为hibernate自动执行了一次 session.flush();

选择什么样的flush mode就是采取对hibernate session采取什么样的数据刷新的策略。
Session.setFlushMode()用于设定清理缓存的时间点。

对比一下几种flush mode:

FlushMode.AUTO:
调用Session的查询方法时,清理缓存,注意:这条规则必须保证显式开启的事务中,对于outside a transaction
调用Session.commit()时,清理缓存
调用Session.flush()时,清理缓存

FlushMode.COMMIT:
调用Session的查询方法时,不清理缓存
调用Session.commit()时,清理缓存
调用Session.flush()时,清理缓存

FlushMode.NEVER(MANUAL):
调用Session的查询方法时,不清理缓存
调用Session.commit()时,不清理缓存
调用Session.flush()时,清理缓存

FlushMode.ALWAYS:测试未发现和auto有什么区别。

调用Session的查询方法时,清理缓存,注意:这条规则必须保证显式开启的事务中,对于outside a transaction
调用Session.commit()时,清理缓存
调用Session.flush()时,清理缓存

=================

三种情况分别在以下时机同步数据库
session.flushmode=manual
1.只有手动调用flush()

session.flushmode=commit
1.手动调用flush()
2.commit()时候

session.flushmode=auto
1.手动调用flush()
2.commit()时候
3.查询前 (经过测试(oracle驱动),必须在事务内,不确定是否全部情形)

==================

  /// <summary>
/// FlushMode.Auto返回1 因为在查询前会刷新缓存 FlushMode.Commit返回0 因为只有Commit之后刷新缓存
/// </summary>
/// <returns></returns>
public int FlushModeAutoTestMethod2()
{
using (var tx = SessionFactoryManager.SessionFactory.GetCurrentSession().BeginTransaction())
{ ISession session = SessionFactoryManager.SessionFactory.OpenSession();
session.FlushMode = FlushMode.Auto;
Cardtype entity =
SessionFactoryManager.SessionFactory.GetCurrentSession()
.CreateQuery("from Cardtype where CardtypeStr = '99'")
.List<Cardtype>()
.FirstOrDefault(); entity.CardtypeStr = "";
var list = SessionFactoryManager.SessionFactory.GetCurrentSession().CreateQuery("from Cardtype where CardtypeStr = '22'").List<Cardtype>().Count(); session.Flush();
tx.Commit();
return list;
}
}

新项目用了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 问题

  1. IQuery q = Session.CreateQuery("select Pic from Pics");
  2. q.SetMaxResults(count);

IQuery q = Session.CreateQuery("select Pic from Pics");
q.SetMaxResults(count);

对象状态不一致问题

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

  1. PersistClass myPer = (PersistClass)session.Load(Typeof(PersistClass), nID);
  2. myPer.C1 = 12;
  3. NHibernateHelper.SaveToDB(myPer);
  4. //call some separat function to update DB column
  5. UpdateColumnC1(nID, 13);
  6. int nCurrentValue = myPer.C1; //now myPer.C1 is still 12!

PersistClass myPer = (PersistClass)session.Load(Typeof(PersistClass), nID);
myPer.C1 = 12;
NHibernateHelper.SaveToDB(myPer);
//call some separat function to update DB column
UpdateColumnC1(nID, 13);
int nCurrentValue = myPer.C1; //now myPer.C1 is still 12!

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

多对多的问题

多对多需要另外一张表,

  1. <set name="VirusSamples" table="autovr_released_virus_table" lazy="false">
  2. <key column="released_id" />
  3. <many-to-many column="virus_id" class="Virus, FtData" />
  4. </set>

<set name="VirusSamples" table="autovr_released_virus_table" lazy="false">
<key column="released_id" />
<many-to-many column="virus_id" class="Virus, FtData" />
</set>

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

session异常

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

一山不容二虎

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

Nhibernate学习的更多相关文章

  1. Nhibernate学习教程(1)-- 开篇有益

    NHibernate之旅(1):开篇有益 本节内容 NHibernate是什么 NHibernate的架构 NHibernate资源 欢迎加入NHibernate中文社区 作者注:2009-11-06 ...

  2. Nhibernate学习的第一天

    书本:https://www.tutorialspoint.com/nhibernate/index.htm 第一天学习内容 概念 Nhibernate是一个ORM框架. ORM框架:将声明的类映射到 ...

  3. NHibernate学习笔记

    原文详见http://www.cnblogs.com/GoodHelper/archive/2011/02/16/nhibernate_03.html   NHibernate_Demo程序框架: D ...

  4. 简单的NHibernate学习笔记

    NHibernate是.NET平台下的ORM框架,与ADO.NET一样实现项目中数据库与项目系统的交互. .首先要用NHibernate框架就要有第三方的dll库来作为支持,附上百度云下载地址:(链接 ...

  5. NHibernate学习教程(6)--事务Transactions

    本节内容 事务概述 1.新建对象 [测试成功提交] [测试失败回滚] 2.删除对象 3.更新对象 4.保存更新对象 结语 上一篇我们介绍了NHibernate中的Insert, Update,  De ...

  6. Nhibernate学习教程(2)-- 第一个NHibernate程序

    NHibernate之旅(2):第一个NHibernate程序 本节内容 开始使用NHibernate 1.获取NHibernate 2.建立数据库表 3.创建C#类库项目 4.设计Domain 4- ...

  7. NHibernate 学习笔记(一)

    NHibernate 的简介: NHibernate是一个面向.NET环境的对象/关系数据库映射工具.对象/关系数据库映射(object/relational mapping (ORM))这个术语表示 ...

  8. 在MVC中使用NHibernate学习记录

    NHibernate简介: NHibernate是一个面向.net环境的对象/关系数据库映射工具,对象/关系数据库映射(object/relational mapping,ORM)是一种技术,可以将对 ...

  9. NHibernate学习系列一

    NHibernate是一个面向.NET环境的对象/关系数据库映射工具.对象/关系数据库映射(object/relational mapping,ORM)这个术语表示一种技术,用来把对象模型表示的对象映 ...

随机推荐

  1. 【VirtualBox】ubuntu虚拟机与windows设置共享文件夹

    第一步:配置 http://blog.csdn.net/a962804835/article/details/72820355 第二步:解决ubuntu下共享文件夹无访问权限的问题 http://bl ...

  2. 详解MathType中如何更改公式颜色

    在MathType数学公式编辑器中可以通过更改公式颜色,起到美化.标注公式的效果.本教程将详解MathType中如何更改公式颜色. 点击菜单栏中的样式->格式->颜色,用户就可以根据自己的 ...

  3. Android开发学习笔记-SharedPreferences的用法

    SharedPreferences介绍:   做软件开发应该都知道,很多软件会有配置文件,里面存放这程序运行当中的各个属性值,由于其配置信息并不多,如果采用数据库来存放并不划算,因为数据库连接跟操作等 ...

  4. linux 中搜索命令的对比

    1.find find是最常用和最强大的查找命令.它能做到实时查找,精确查找,但速度慢. find的使用格式如下: #find [指定目录] [指定条件] [指定动作] 指定目录:是指所要搜索的目录和 ...

  5. python类和模块区别,python命名空间

    在python中,类可以提供模块级别之下的命名空间. 如果一个模块写很多函数,某些函数之间共同完成一组功能,用类会看起来更清晰,在调用时候也会更好,对于ide补全有更小范围的限定提示. 类提供 继承 ...

  6. c++String类的运算符重载---21

    原创博文,转载请标明出处--周学伟http://www.cnblogs.com/zxouxuewei/  一,创建测试程序包 测试代码如下: /* Date: 2017-5-4 * Descripti ...

  7. Linux Top命令详解(载自百度经验)

    Linux系统可以通过top命令查看系统的CPU.内存.运行时间.交换分区.执行的线程等信息.通过top命令可以有效的发现系统的缺陷出在哪里.是内存不够.CPU处理能力不够.IO读写过高. 1 使用S ...

  8. cocos2dx 3.0 scrollview 在android下面背景變綠色了

    在windows上面跑的是OK的,  在android下面跑的時候就變成這樣子了:

  9. centos7修改root密码

    1.重启系统,在下面界面时按e键 2.出现可编辑新内容,按向下键向下滑动,找到ro,并修改为rw 后,在LANG=en_US.UTF-8后面再加init=/bin/sh,结果如下图 3.然后按下ctr ...

  10. 一句话木马:PHP篇

    珍藏版: 一个简单的过D盾的免杀php <?php $ab = $_REQUEST['d']; $a['t'] = "";//主要带对象 D盾就不管后面的了... eval( ...