[Nhibernate]对象状态
目录
写在前面
文档与系列文章
对象状态
瞬时态(Transient)
持久态(Persistent)
脱管态(Detached)
对象状态转换
总结
写在前面
前面两篇文章介绍了SchemaExport工具的使用,使用该工具可以根据映射文件生成数据库架构,这篇文章将介绍nhibernate中的三种对象状态。
在程序运行过程中,使用对象的方式操作数据库的同时,必然会产生一系列的持久化对象。这些对象可能是刚刚创建并准备进行存储的,也有可能是从数据库进行查询得到的,为了区别这些对象,根据对象和当前Session的关联状态,可以将对象分为三种:
瞬时对象:对象刚刚建立,该对象没有在数据库中进行存储,也没有在ISession的缓存中。如果该对象的主键是自动创建的,则此时对象的标识符为空。
持久化对象:对象已经通过Nhibernate进行了持久化,数据库中已经存在了该对象的记录。如果该对象自动创建主键,则此时对象的标识符已被赋值。
托管对象:该对象已经通过NHIbernate保存或者从数据库中查询取出的,但与此对象关联的ISession已经关闭。虽然它存在对象标识符,且在数据库中也有对应的记录,但已经不被Nhibernate管理的。
文档与系列文章
[Nhibernate]体系结构
[NHibernate]ISessionFactory配置
[NHibernate]持久化类(Persistent Classes)
[NHibernate]O/R Mapping基础
[NHibernate]集合类(Collections)映射
[NHibernate]关联映射
[NHibernate]Parent/Child
[NHibernate]缓存(NHibernate.Caches)
[NHibernate]NHibernate.Tool.hbm2net
[NHibernate]Nullables
[NHibernate]Nhibernate如何映射sqlserver中image字段
[NHibernate]基本配置与测试
[NHibernate]HQL查询
[NHibernate]条件查询Criteria Query
[NHibernate]增删改操作
[NHibernate]事务
[NHibernate]并发控制
[NHibernate]组件之依赖对象
[NHibernate]一对多关系(级联删除,级联添加)
[NHibernate]一对多关系(关联查询)
[NHibernate]多对多关系(关联查询)
[NHibernate]延迟加载
[NHibernate]立即加载
[NHibernate]视图处理
[NHibernate]N+1 Select查询问题分析
[NHibernate]存储过程的使用(一)
[NHibernate]存储过程的使用(二)
[NHibernate]存储过程的使用(三)
[Nhibernate]SchemaExport工具的使用(一)——通过映射文件修改数据表
[Nhibernate]SchemaExport工具的使用(二)——创建表及其约束、存储过程、视图
对象状态
NHibernate提供了对象状态管理的功能,支持三种对象状态:瞬时态(Transient)、持久态(Persistent)、脱管态(Detached)。
瞬时态(Transient)
对象刚刚创建,还没有来及和ISession关联的状态。这时瞬时对象不会被持久化到数据库中,也不会被赋上标识符。如果不使用则被GC销毁。ISession接口可以将其转换为持久状态。
例如:刚刚创建一个Customer对象,就是一个瞬时态的对象。
1 //瞬时态对象 2 var customer = new Customer() 3 { 4 CustomerID = Guid.NewGuid(), 5 NameAddress = new Name() 6 { 7 CustomerAddress="北京", 8 CustomerName="wolfy" 9 }, 10 Orders=null, 11 Version=1 12 };
持久态(Persistent)
刚被保存的或刚从数据库中加载的。对象仅在关联的ISession生命周期内有效,在数据库中有相应记录并有标识符。对象实例由NHibernate框架管理,如果有任何改动,在提交时,与数据库同步,即将对象保存更新到数据库中。
脱管态(Detached)
持久对象关联的ISession关闭后,这个对象在ISession中脱离了关系,就是脱管态了,托管对象仍然有持久对象的所有属性,对托管对象的引用仍然有效的,我们可以继续修改它。如果把这个对象重新关联到ISession上,则再次转变为持久态,在托管时期的修改会被持久化到数据库中。
对象状态转换
在同步数据库的情况下执行下面的语句可以转换对象的状态。
ISession.Contains(object):检查ISession中是否包含指定实例
添加一个ISession的重置方法
1 public static ISession ResetSession() 2 { 3 if (_session.IsOpen) 4 _session.Close(); 5 _session = _sessionFactory.OpenSession(); ; 6 return _session; 7 }
瞬时态转换为持久态
方法一:ISession.Save():保存指定实例。
1 public void TransientConvertPersistent() 2 { 3 //瞬时态对象 4 var customer = new Customer() 5 { 6 CustomerID = Guid.NewGuid(), 7 NameAddress = new Name() 8 { 9 CustomerAddress="北京", 10 CustomerName="wolfy" 11 }, 12 Orders=null, 13 Version=1 14 }; 15 ISession session = NHibernateHelper.GetSession(); 16 if (!session.Contains(customer)) 17 { 18 //关联ISession保存到数据库中 19 session.Save(customer); 20 } 21 //变为持久态,由于表中CustomerId字段自动增长的(如果是自动增长主键),保存数据库,CustomerId字段自动加一 22 //经过NHibernate类型转换后返回CustomerId属性值,保证数据库与实例对象同步 23 if (session.Contains(customer)) 24 { 25 26 } 27 }
方法二:ISession.SaveOrUpdate():分配新标识保存瞬时态对象。
持久态转换为脱管态
方法一:ISession.Evict(object):从当前ISession中删除指定实例
1 public void PersistentConvertDetachedEvict() 2 { 3 //得到session 4 ISession session = NHibernateHelper.GetSession(); 5 //根据id得到customer对象 6 var customer = session.Get("Customer", new Guid("DDF63750-3307-461B-B96A-7FF356540CB8")); 7 //如果包含customer对象则删除 8 if (session.Contains(customer)) 9 { 10 session.Evict(customer); 11 } 12 }
方法二:ISession.Close():关闭当前ISession
1 public void PersistentConvertDetachedCloseTest() 2 { 3 //得到session 4 ISession session = NHibernateHelper.GetSession(); 5 //根据id得到customer对象 6 var customer = session.Get("Customer", new Guid("DDF63750-3307-461B-B96A-7FF356540CB8")); 7 if (session.Contains(customer)) 8 { 9 NHibernateHelper.ResetSession(); 10 } 11 }
脱管态转换为持久态
方法一:ISession.Update():更新指定实例。
1 public void DetachedConvertPersistentUpdateTest() 2 { 3 //得到session 4 ISession session = NHibernateHelper.GetSession(); 5 //根据id得到customer对象 6 Customer customer = session.Get("Customer", new Guid("DDF63750-3307-461B-B96A-7FF356540CB8")) as Customer; 7 //重新设置ISession 8 NHibernateHelper.ResetSession(); 9 //脱管态对象 10 //在脱管态下可继续被修改 11 if (session.Contains(customer)) 12 { 13 customer.NameAddress = new Name() { CustomerAddress="上海", CustomerName="wolfy"}; 14 //转变为持久态对象 15 session.Update(customer); 16 } 17 }
通过上面的例子可以看出:在托管时期的修改会被持久化到数据库中;
注意:NHibernate如何知道重新关联的对象是不是“脏的(修改过的)”?如果是新的ISession,ISession就不能与对象初值来比较这个对象是不是“脏的”,我们在映射文件中定义<id>元素和<version>元素的unsaved-value属性,NHibernate就可以自己判断了。
如果加上一个锁:如果在托管时期没有修改,就不执行更新语句,只转换为持久态,下面的例子如果在托管时期修改对象,执行更新语句。
1 public void DetachedConvertPersistentUpdateLockTest() 2 { 3 //得到session 4 ISession session = NHibernateHelper.GetSession(); 5 //根据id得到customer对象 6 Customer customer = session.Get("Customer", new Guid("DDF63750-3307-461B-B96A-7FF356540CB8")) as Customer; 7 if (session.Contains(customer)) 8 { 9 NHibernateHelper.ResetSession(); 10 } 11 //锁 12 session.Lock(customer, NHibernate.LockMode.None); 13 //如果在托管时期没有修改,就不执行更新语句,只转换为持久态 14 session.Update(customer); 15 }
需注意Lock锁的使用,需要保证customer对象不为null,这里为了测试方便就没加上判断。如果为null会有异常(attempt to lock null)。
方法二:ISession.Merge():合并指定实例。不必考虑ISession状态,ISession中存在相同标识的持久化对象时,NHibernate便会根据用户给出的对象状态覆盖原有的持久化实例状态。
方法三:ISession.SaveOrUpdate():分配新标识保存瞬时态对象;更新/重新关联脱管态对象。
总结
本篇概念性的东西比较多,对三种状态的理解到位,就能区别三种状态。
参考文章
http://www.cnblogs.com/lyj/archive/2008/11/17/1335181.html
[Nhibernate]对象状态相关推荐
- Hibernate 几种对象状态
Hibernate 中四种对象状态 临时状态(transient):刚用new 语句创建,还没有被持久化,并且不处于Sesssion 的缓存中.处于临时状态 的Java 对象被称为临时对象. 持久化状 ...
- Hibernate_2_Hibernate中对象状态及转化_一级缓存_Session详解_HQL/SQL/Criteria_一对多关系_级联操作
Hibernate中的对象状态 在Hibernate中持久化对象具有三种状态: 瞬时态, 持久态, 游离态. 瞬时态: 对象没有与Hibernate产生关联(transient,session中没有缓 ...
- Hibernate开发和对象状态
Hibernate开发和对象状态 Hibernate开发三种方式 1.由Domain object -> mapping->db.(官方推荐) 2.由DB开始,用工具生成mapping和D ...
- 5 -- Hibernate的基本用法 --5 3 改变持久对象状态的方法
1. 持久化实体 Serializable save(Object obj) : 将obj对象变为持久化状态,该对象的属性将被保存到数据库. void persist(Object obj) : 将o ...
- java对象gc恢复_JVM垃圾回收与对象状态
看到JVM就不得不说垃圾回收,说到垃圾回收(Garbage Collection,GC),顾名思义,垃圾回收就是释放垃圾占用的空间,在Java中,程序员不需要去关心内存动态分配和垃圾回收的问题,这一切 ...
- 对象池common-pool2源码分析之对象状态
2019独角兽企业重金招聘Python工程师标准>>> 对象池common-pool2源码分析 对象池common-pool2策略分析 从前两篇的分析中可以看出对象池中的对象会被激活 ...
- Hibernate学习笔记_核心幵发接口及三种对象状态
核心接口开发 (重点) 一, Configuration a) AnnotationConfi ...
- Hibernate→HQL、query.list()返回数据类型、查询相关语句、分页、原生SQL、@注解、持久化对象状态及生命周期、一多关系、继承映射关系、逆向工程
HQL Query实例与表 session通用工具类 Query对象 from 类→List<类>接收 映射类 仅查询商品 查询商品及所在商家 别名 返回数据类型定义 Iterator接收 ...
- python怎么在运行中查看执行状态_python,_python程序运行时 查看对象状态,python - phpStudy...
python程序运行时 查看对象状态 不知大家有没有用过Rthymbox的python console. Rthymbox可以在运行的时候,让它的 交互式命令行 对程序进行控制. 比如说可以调用pla ...
最新文章
- 码农技术炒股之路——任务管理器
- 四、编译安装php-5.5.34
- xpath解析库的语法及使用
- 第1章 编程心理门槛
- C++连接MySQL(Windows)
- c语言教程苏小红,《数据结构(C语言)》苏小红 课本案例
- 初探image-set及如何适配移动端高清屏图片
- spring 4 异常HttpMediaTypeNotAcceptableException解决方案
- c++ string 长度限制_面试中要会的String相关问题
- 你与30W奖金只差一个 Apache Flink 极客挑战赛的报名
- 能力提升综合题单 Part 8.7 图的连通性相关
- gitee创建仓库,并将代码上传到gitee上
- 中国互联网用户各阶级的分析
- 汽车的主要结构参数和性能参数
- jBox,实现批量查询
- 2019八泉峡第二届国际露营大会即将开启
- 正雅GS颌位重建技术为隐形正畸打开新篇章
- Python编程语言好学吗? 零基础转行能学Python吗?
- VMR论文visualization实验总结
- 144.如何评价个性化推荐系统的效果-1
热门文章
- [PHP] PHP 格式化日期 format the datetime in PHP
- Linux计划任务与压缩归档
- JSP页面中验证码的调用方法
- 编写 Shell 脚本的最佳实践
- mac 使用svn记录
- android常见错误-Installation error: INSTALL_FAILED_INSUFFICIENT_STORAGE
- 在Debian中建立Beaglebone black的应用开发环境之四:如何布置应用?
- apache用proxy 实现URL 转发
- 【C#学习笔记】退出程序
- django之Ajax