博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[Nhibernate]对象状态
阅读量:6291 次
发布时间:2019-06-22

本文共 5663 字,大约阅读时间需要 18 分钟。

目录

写在前面

前面两篇文章介绍了SchemaExport工具的使用,使用该工具可以根据映射文件生成数据库架构,这篇文章将介绍nhibernate中的三种对象状态。

在程序运行过程中,使用对象的方式操作数据库的同时,必然会产生一系列的持久化对象。这些对象可能是刚刚创建并准备进行存储的,也有可能是从数据库进行查询得到的,为了区别这些对象,根据对象和当前Session的关联状态,可以将对象分为三种:

瞬时对象:对象刚刚建立,该对象没有在数据库中进行存储,也没有在ISession的缓存中。如果该对象的主键是自动创建的,则此时对象的标识符为空。

持久化对象:对象已经通过Nhibernate进行了持久化,数据库中已经存在了该对象的记录。如果该对象自动创建主键,则此时对象的标识符已被赋值。

托管对象:该对象已经通过NHIbernate保存或者从数据库中查询取出的,但与此对象关联的ISession已经关闭。虽然它存在对象标识符,且在数据库中也有对应的记录,但已经不被Nhibernate管理的。

文档与系列文章

 

 

 

对象状态

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/wolf-sun/p/4124960.html
你可能感兴趣的文章
将图片转成base64字符串并在JSP页面显示的Java代码
查看>>
js 面试题
查看>>
sqoop数据迁移(基于Hadoop和关系数据库服务器之间传送数据)
查看>>
腾讯云下安装 nodejs + 实现 Nginx 反向代理
查看>>
Javascript 中的 Array 操作
查看>>
java中包容易出现的错误及权限问题
查看>>
AngularJS之初级Route【一】(六)
查看>>
服务器硬件问题整理的一点总结
查看>>
SAP S/4HANA Cloud: Revolutionizing the Next Generation of Cloud ERP
查看>>
Mellanox公司计划利用系统芯片提升存储产品速度
查看>>
白帽子守护网络安全,高薪酬成大学生就业首选!
查看>>
ARM想将芯片装进人类大脑 降低能耗是一大挑战
查看>>
Oracle数据库的备份方法
查看>>
Selenium 自动登录考勤系统
查看>>
关于如何以编程的方式执行TestNG
查看>>
智能照明造福千家万户 家居智能不再是梦
查看>>
物联网如何跳出“看起来很美”?
查看>>
浅谈MySQL 数据库性能优化
查看>>
《UNIX/Linux 系统管理技术手册(第四版)》——1.10 其他的权威文档
查看>>
灵动空间 创享生活
查看>>