• 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缓存、离线查询等内容。

  • 相关阅读:
    iOS resign code with App Store profile and post to AppStore
    HTTPS科普扫盲帖 对称加密 非对称加密
    appid 评价
    使用Carthage安装第三方Swift库
    AngularJS:何时应该使用Directive、Controller、Service?
    xcode7 The operation couldn't be completed.
    cocoapods pod install 安装报错 is not used in any concrete target
    xcode7 NSAppTransportSecurity
    learning uboot how to set ddr parameter in qca4531 cpu
    learning uboot enable protect console
  • 原文地址:https://www.cnblogs.com/easy5weikai/p/3758209.html
Copyright © 2020-2023  润新知