01-08-01【Nhibernate (版本3.3.1.4000) 出入江湖】NHibernate中的三种状态
以下属于不明来源资料:
引入
在程序运行过程中使用对象的方式对数据库进行操作,这必然会产生一系列的持久化类的实例对象。这些对象可能是刚刚创建并准备存储的,也可能是从数据库中查询的,为了区分这些对象,根据对象和当前会话的关联状态,我们可以把对象分为三种:
瞬时对象:对象刚刚建立。该对象在数据库中没有记录,也不在ISession缓存中。如果该对象是自动生成主键,则该对象的对象标识符为空。
持久化对象:对象已经通过NHibernate进行了持久化,数据库中已经存在对应的记录。如果该对象是自动生成主键,则该对象的对象标识符已被赋值。
托管对象:该对象是经过NHibernate保存过或者从数据库中取出的,但是与之关联的ISession已经关闭。虽然它有对象标识符且数据库中存在对应记录,但是已经不再被NHibernate管理。
对象状态
NHibernate提供了对象状态管理的功能,支持三种对象状态:瞬时态(Transient)、持久态(Persistent)、托管态(Detached)。
1.瞬时态(Transient)
对象刚刚创建,还没有来及和ISession关联的状态。这时瞬时对象不会被持久化到数据库中,也不会被赋上标识符。如果不使用则被GC销毁。ISession接口可以将其转换为持久状态。
这像这样,刚刚创建了一个Customer对象,是一个瞬时态对象:
var customer = new Customer() { Firstname = "zhang", Lastname = "san" };
2.持久态(Persistent)
刚被保存的或刚从数据库中加载的。对象仅在相关联的ISession生命周期内有效,在数据库中有相应记录并有标识符。对象实例由NHibernate框架管理,如果有任何改动,在当然操作提交时,与数据库同步,即将对象保存更新到数据库中。
3.托管态(Detached)
持久对象关联的ISession关闭后,这个对象在ISession中脱离了关系,就是托管态了,托管对象仍然有持久对象的所有属性,对托管对象的引用仍然有效的,我们可以继续修改它。如果把这个对象重新关联到ISession上,则再次转变为持久态,在托管时期的修改会被持久化到数据库中。
对象状态转换
在同步数据库的情况下执行下面的语句可以转换对象的状态。
测试验证对象
ISession.Contains(object):检查ISession中是否包含指定实例
重新设置ISession
private void ResetSession()
{
if (_session.IsOpen)
_session.Close();
_session = _sessionManager.GetSession();
_transaction.Session = _session;
}
1.瞬时态转换持久态
方法一:ISession.Save():保存指定实例。
[Test]
public void TransientConvertPersistentTest()
{
//瞬时态对象
var customer = new Customer() { Firstname = "zhang", Lastname = "san" };
Assert.IsFalse(_session.Contains(customer));
//仍然是瞬时态,CustomerId属性值为空
//关联ISession保存到数据库中
_session.Save(customer);
//变为持久态,由于表中CustomerId字段自动增长的,保存数据库,CustomerId字段自动加一
//经过NHibernate类型转换后返回CustomerId属性值,保证数据库与实例对象同步
Assert.IsTrue(_session.Contains(customer));
}
方法二:ISession.SaveOrUpdate():分配新标识保存瞬时态对象。
2.持久态转换托管态
方法一:ISession.Evict(object):从当前ISession中删除指定实例
[Test]
public void PersistentConvertDetachedEvictTest()
{
Customer customer = _transaction.GetCustomerById(1);
Assert.IsTrue(_session.Contains(customer));
_session.Evict(customer);
Assert.IsFalse(_session.Contains(customer));
}
方法二:ISession.Close():关闭当前ISession
[Test]
public void PersistentConvertDetachedCloseTest()
{
Customer customer = _transaction.GetCustomerById(1);
Assert.IsTrue(_session.Contains(customer));
ResetSession();
Assert.IsFalse(_session.Contains(customer));
}
3.托管态转换持久态
方法一:ISession.Update():更新指定实例。
[Test]
public void DetachedConvertPersistentUpdateTest()
{
Customer customer = _transaction.GetCustomerById(1);
//持久态对象
Assert.IsTrue(_session.Contains(customer));
//重新设置ISession
ResetSession();
Assert.IsFalse(_session.Contains(customer));
//托管态对象
//在托管态下可继续被修改
customer.Firstname += "CnBlogs";
_transaction.UpdateCustomerTransaction(customer);
//转变为持久态对象
Assert.IsTrue(_session.Contains(customer));
}
看看这个例子:在托管时期的修改会被持久化到数据库中;
注意:NHibernate如何知道重新关联的对象是不是“脏的(修改过的)”?如果是新的ISession,ISession就不能与对象初值来比较这个对象是不是“脏的”,我们在映射文件中定义<id>元素和<version>元素的unsaved-value属性,NHibernate就可以自己判断了。
[Test]
public void DetachedConvertPersistentUpdateAllTest()
{
Customer customer = _transaction.GetCustomerById(1);
//持久态对象
customer.Firstname += "zhang";
Assert.IsTrue(_session.Contains(customer));
//重新设置ISession
ResetSession();
Assert.IsFalse(_session.Contains(customer));
//托管态对象
//在托管态下可继续被修改
customer.Firstname += "CnBlogs";
//这时一起更新
_transaction.UpdateCustomerTransaction(customer);
//转变为持久态对象
Assert.IsTrue(_session.Contains(customer));
}
现在我们初步知道了对象的状态。虽然对象的状态的细节由NHibernate自己维护,但是对象状态在NHibernate应用中还是比较重要的。同时对象状态也涉及了NHibernate缓存、离线查询等内容。
01-08-01【Nhibernate (版本3.3.1.4000) 出入江湖】NHibernate中的三种状态的更多相关文章
- 01-08-05【Nhibernate (版本3.3.1.4000) 出入江湖】NHibernate二级缓存:第三方MemCache缓存
一.准备工作 [1]根据操作系统(位数)选择下载相应版本的MemCache, MemCache的下载和安装,参看: http://www.cnblogs.com/easy5weikai/p/37606 ...
- 01-03-02-2【Nhibernate (版本3.3.1.4000) 出入江湖】CRUP操作-Save方法的一些问题
此文由于当时不知道NHibernate的Sava方法不是更新操作,不知道Save就是Add,造成如下荒唐的求证过程,但结论是对的 ,可报废此文,特此声明. NHibernate--Save方法: Cu ...
- 01-07-01【Nhibernate (版本3.3.1.4000) 出入江湖】并发控制
Nhibernate 并发控制 [1]悲观并发控制 正在使用数据的操作,加上锁,使用完后解锁释放资源. 使用场景:数据竞争激烈,锁的成本低于回滚事务的成本 缺点:阻塞,可能死锁 [2]乐观并发控制: ...
- 01-08-03【Nhibernate (版本3.3.1.4000) 出入江湖】二级缓存:NHibernate自带的HashtableProvider之缓存管理
http://www.cnblogs.com/lyj/archive/2008/11/28/1343418.html 管理NHibernate二级缓存 NHibernate二级缓存由ISessionF ...
- 01-08-04【Nhibernate (版本3.3.1.4000) 出入江湖】二级缓存:NHibernate自带的HashtableProvider之命名缓存
http://www.cnblogs.com/lyj/archive/2008/11/28/1343418.html 可以在映射文件中定义命名查询,<query>元素提供了很多属性,可以用 ...
- 01-08-02【Nhibernate (版本3.3.1.4000) 出入江湖】二级缓存:NHibernate自带的HashtableProvider
第一步骤:hibernate.cfg.xml文件补上如下配置: <?xml version="1.0" encoding="utf-8"?> < ...
- 01-08-01【Nhibernate (版本3.3.1.4000) 出入江湖】NHibernate中的一级缓存
缓存的范围? 1.事务范围 事务范围的缓存只能被当前事务访问,每个事务都有各自的缓存,缓存内的数据通常采用相互关联的对象形式.缓存的生命周期依赖于事务的生命周期,只有当事务结束时,缓存的生命周期才会结 ...
- 01-06-01【Nhibernate (版本3.3.1.4000) 出入江湖】事务
Nhibernate事务的使用: public void Add(Customer customer) { ISession session = _sessionManager.GetSession( ...
- 01-05-01-2【Nhibernate (版本3.3.1.4000) 出入江湖】立即加载实现--NHibernateUtil.Initialize()和添加fetch关键字的HQL查询
相关资料: http://www.cnblogs.com/lyj/archive/2008/10/29/1322373.html 问题的提出: 1.延迟加载,可能会引起session已经关闭的异常,例 ...
随机推荐
- Objective-C 【protocol-协议 的了解使用】
------------------------------------------- protocol(协议) (1)引文:OC中的protocol和Java中的接口(interface)比较类似, ...
- 《锋利的jQuery》心得笔记--Four Sections
第八章 1. 当父元素设置position:relative的时候,子元素设置position:absolute.这个子元素设置在父元素的任何位置. 第九章 1. 对可视区进行纠正,通知浏 ...
- CString使用
1. 空间分配,如果不是它自己的空间分配方式,需要用函数来手动分配空间,否则大家指向同一块地址,取得内容一样 例子,读取文件到CString ,没有给CString 对象分配空间,而且不是他定义的开拓 ...
- UIPickerView基本用法
#import "ViewController.h" #import <UIKit/UIKit.h> @interface ViewController : UIVie ...
- UIView背景渐变三种方法
//此作品非原创 #import "ACViewController.h" @interface ACViewController () @end @implementation ...
- 最新区分兼容IE6/IE7/IE8/IE9/FF的CSS HACK写法和Css if hack条件语法操作说明
自从安装了IE8.0正式版本!木头 就对基本的几个 CSS HACK的做一下归纳!希望对网页前端布局DIV+CSS的实施者有所帮助! 本文就主要以:IE6+IE7+IE8+IE9+FF为主要研究对象 ...
- Android:什么是Holo?【Translated By KillerLegend】
Android:什么是Holo? Martin Brinkmann on May 6, 2013 in Google Android 3 [Translated By KillerLegend] 当你 ...
- DataSnap中连接池的应用
当开发人员开始创建Delphi的DataSnap应用时很常见的数据库连接定义方式是每个数据模块建立一个连接.这样做将产生大量的数据库连接,并产生很多问题.从Delphi XE开始,EMB提供了Sess ...
- 括弧匹配检验(check)
/*题目:括弧匹配检验 检验给定表达式中括弧是否正确匹配 (两种括弧“( ) ”“[]" ,正确输出OK,错误则输出wrong. 2016年8月8日07:24:58 作者:冰樱梦 */ # ...
- SQL随机数的生成
下面是一个随机函数问题,获取两位数的随机数,且不重复. 但是说明一下,这个函数有点bug,例如:两位数的函数最后能生成89个,如果将数量改成90,那么就无法生成,陷入死循环了. IF object_i ...