zoukankan      html  css  js  c++  java
  • NHibernate 状态的概念 以及 小测试

    在 NHibernate中有三种状态。

    • 临时态(Transient):用new创建的对象,它没有持久化,没有纳入Session中,随时可以被垃圾回收,处于此状态的对象叫临时对象。特点:数据库中没有与之对应的记录;
    • 持久态(Persistent):已经持久化,加入到了Session缓存中。通过NHibernate保存的对象或通过Get/Load等方法获取出的对象,其对象没有脱离Session的管理,处于此状态的对象叫持久对象;
    • 游离态(Detached):持久化对象脱离了Session的对象。如Session缓存被清空的对象。特点:已经持久化,但不在Session缓存中。处于此状态的对象叫游离对象;

     临时态(Transient)到持久态(Persistent)

    先new一个对象,该对象的状态为Transient,然后调用Save()方法将该对象持久化到数据库中,该对象的状态变为Persistent。在未关闭Session前,修改该对象的属性,最后提交事务。

     1   /// <summary>
     2         /// 临时态-->持久态
     3         /// </summary>
     4         [Test]
     5         public void TransientToPersistentTest()
     6         {
     7             using (ISession session = this.sessionFactory.OpenSession())
     8             {
     9                 using (ITransaction tran = session.BeginTransaction())
    10                 {
    11                     //Transient
    12                     var product = new Product
    13                     {
    14                         ID = Guid.NewGuid(),
    15                         BuyPrice = 10M,
    16                         Code = "ABC123",
    17                         Name = "电脑",
    18                         QuantityPerUnit = "20x1",
    19                         SellPrice = 11M,
    20                         Unit = ""
    21                         
    22                     };  
    23 
    24                     try
    25                     {
    26                         //Persistent
    27                         session.Save(product);
    28 
    29                         //保存记录后修改数据,观察数据库中数据的变化
    30                         product.SellPrice = 12M;
    31 
    32                         tran.Commit();
    33                     }
    34                     catch (Exception ex)
    35                     {
    36                         tran.Rollback();
    37                         throw ex;
    38                     }
    39                 }
    40             }
    41         }

    这时,我们心里便产生了一个疑问:把Product的SellPrice属性从“11M”修改为“12M”后,并没有调用Save()或者Update()的方法,为什么数据库中的数据会变呢?

      这是因为,当对象处于Persistent状态,并没有脱离Session管理时,其属性发生改变后,数据库相对应的记录会与之同步

    持久态(Persistent)到游离态(Detached),再到持久态(Persistent)

     1  /// <summary>
     2         /// 持久态-->游离态-->持久态
     3         /// </summary>
     4         [Test]
     5         public void PersistentToTestDetached()
     6         {
     7             //Transient
     8             var product = new Product
     9             {
    10                 ID = Guid.NewGuid(),
    11                 BuyPrice = 10M,
    12                 Code = "ABC123",
    13                 Name = "电脑",
    14                 QuantityPerUnit = "20x1",
    15                 SellPrice = 11M,
    16                 Unit = ""
    17             };
    18 
    19             using (ISession session = this.sessionFactory.OpenSession())
    20             {
    21                 using (ITransaction tran = session.BeginTransaction())
    22                 {                
    23                     try
    24                     {
    25                         //Persistent
    26                         session.Save(product);
    27                         product.SellPrice = 12M;
    28 
    29                         tran.Commit();
    30                     }
    31                     catch (Exception ex)
    32                     {
    33                         tran.Rollback();
    34                         throw ex;
    35                     }
    36                 }
    37             }
    38 
    39             //Detached
    40             product.SellPrice = 13M;
    41 
    42             using (ISession session = this.sessionFactory.OpenSession())
    43             {
    44                 using (ITransaction tran = session.BeginTransaction())
    45                 {
    46                     try
    47                     {
    48                         //Persistent
    49                         session.Update(product);
    50                         tran.Commit();
    51                     }
    52                     catch (Exception ex)
    53                     {
    54                         tran.Rollback();
    55                         throw ex;
    56                     }
    57                 }
    58             }
    59         }

    当对象处于游离态(Detached)时,修改其属性,是不会与数据库发生同步的。调用Update()方法后,对象则变回持久态(Persistent)。

    Get方法得到持久态(Persistent)

     1         [Test]
     2         public void PersistentToTestDetached()
     3         {
     4             //Transient
     5             string  ID1 = Guid.NewGuid().ToString();
     6             var product = new Product
     7             {
     8                 ID = ID1,
     9                 BuyPrice = 10M,
    10                 Code = "ABC123",
    11                 Name = "电脑",
    12                 QuantityPerUnit = "20x1",
    13                 SellPrice = 11M,
    14                 Unit = ""
    15             };
    16 
    17             using (ISession session = this.sessionFactory.OpenSession())
    18             {
    19                 using (ITransaction tran = session.BeginTransaction())
    20                 {
    21                     try
    22                     {
    23                         //Persistent
    24                         session.Save(product);
    25                         product.SellPrice = 12M;
    26 
    27                         tran.Commit();
    28                     }
    29                     catch (Exception ex)
    30                     {
    31                         tran.Rollback();
    32                         throw ex;
    33                     }
    34                 }
    35             }
    36 
    37             //Detached
    38            
    39 
    40             using (ISession session = this.sessionFactory.OpenSession())
    41             {
    42                 using (ITransaction tran = session.BeginTransaction())
    43                 {
    44                     try
    45                     {
    46                         //Persistent
    47                         product=session.Get<Product>(ID1);//Get可与Load互换
    48                         product.SellPrice = 18M;
    49                         tran.Commit();
    50                     }
    51                     catch (Exception ex)
    52                     {
    53                         tran.Rollback();
    54                         throw ex;
    55                     }
    56                 }
    57             }
    58         }

    其中ID1为数据库中已存在的一条数据的主键值。在得到持久化对象后,我们便可以更改数据库的值。

     Get和Load()方法的区别

    Load:

    • Load方法可以对查询进行优化。
    • Load方法实际得到一proxy对象,并不立即查询数据库。当访问对象的属性的时候才查询数据库。在NHibernate里称为Lazy Loding(延迟加载)。
    • Load方法得到的对象,如果对象不存在,在访问对象的属性时将抛出异常。
    • 当需要得到实体对象,但是不需要访问对象属性的时候,宜使用Load方法。比如Delete方法:

       调用Load()方法查询数据库中不存在的对象,返回值不为空;当调用Load()方法时,不立刻产生SQL语句,查看其属性后才产生SQL语句,并且查看数据库中不存在对象的属性时会抛出异常。原因是调用Load()方法会返回一个“代理类”,这是NHibernate的一个重要的特性——延迟加载。

     延迟加载(lazy load)也叫“懒加载”,是NHibernate关联关系对象默认的加载方式,延迟加载机制是为了避免一些无谓的性能开销而提出来的,所谓延迟加载就是当在真正需要数据的时候,才真正执行数据加载操作。可以简单理解为,只有在使用的时候,才会发出SQL语句进行查询。 延迟加载的有效期是在Session打开的情况下,当Session关闭后,会报异常。NHibernate的代理对象是由第三方组件“Antlr3.Runtime”提供的。

    Get:

    • Get方法立即查询数据库,如果对象不存在,返回null。
    • 调用Get()方法后,数据库中不存在的对象返回值为null,并且一但调用Get()方法,就会生成SQL语句。

    Update()方法

    先手动打造new一个数据库中存在的游离态(Detached)对象,然后直接调用Update()方法将对象的状态设置为持久态(Persistent)。

     1    [Test]
     2         public void UpdateTest()
     3         {
     4             Guid id = Guid.NewGuid();
     5 
     6             using (ISession session = this.sessionFactory.OpenSession())
     7             {             
     8                 using (ITransaction tran = session.BeginTransaction())
     9                 {
    10                     //Transient
    11                     var product = new Product
    12                     {
    13                         ID = id,
    14                         BuyPrice = 10M,
    15                         Code = "ABC123",
    16                         Name = "电脑",
    17                         QuantityPerUnit = "20x1",
    18                         SellPrice = 11M,
    19                         Unit = ""
    20 
    21                     };
    22 
    23                     try
    24                     {
    25                         //Persistent
    26                         session.Save(product);
    27                         tran.Commit();
    28                     }
    29                     catch (Exception ex)
    30                     {
    31                         tran.Rollback();
    32                         throw ex;
    33                     }
    34                 }
    35             }
    36 
    37             using (ISession session = this.sessionFactory.OpenSession())
    38             {
    39                 using (ITransaction tran = session.BeginTransaction())
    40                 {
    41                     //Detached
    42                     var product = new Product
    43                     {
    44                         ID = id,
    45                         Code = "ABC456",
    46                     };
    47 
    48                     try
    49                     {
    50                         //Persistent
    51                         session.Update(product);
    52 
    53                         tran.Commit();
    54                     }
    55                     catch (Exception ex)
    56                     {
    57                         tran.Rollback();
    58                         throw ex;
    59                     }
    60                 }
    61             }
    62         }

    有的朋友就会问,为什么new的时候也能得到游离态(Detached)对象?因为判断是否为游离态(Detached)对象,是根据数据库中是否存在与之对应的记录定夺的。

     Delete()方法

    先得到一个持久态(Persistent)对象,然后调用Delete()方法删除该对象,这时该对象变回临时态(Transient)

     1  [Test]
     2         public void DeleteTest()
     3         {
     4             using (ISession session = this.sessionFactory.OpenSession())
     5             {
     6                 using (ITransaction tran = session.BeginTransaction())
     7                 {
     8                     //Transient
     9                     var product = new Product
    10                     {
    11                         ID = Guid.NewGuid(),
    12                         BuyPrice = 10M,
    13                         Code = "ABC123",
    14                         Name = "电脑",
    15                         QuantityPerUnit = "20x1",
    16                         SellPrice = 11M,
    17                         Unit = ""
    18 
    19                     };
    20 
    21                     try
    22                     {
    23                         //Persistent
    24                         session.Save(product);
    25 
    26                         //Transient
    27                         session.Delete(product);
    28 
    29                         tran.Commit();
    30                     }
    31                     catch (Exception ex)
    32                     {
    33                         tran.Rollback();
    34                         throw ex;
    35                     }
    36                 }
    37             }
    38         }

    学习于      http://www.cnblogs.com/GoodHelper/archive/2011/02/17/nhibernate_04.html

  • 相关阅读:
    以链表为载体学习C++(1)
    以链表为载体学习C++(2)
    20191304商苏赫Python程序设计实验一
    Python实验二 20191304商苏赫
    七大基本排序算法之插入排序
    七大基本排序算法之归并排序
    《富爸爸,穷爸爸》
    七大基本排序算法之冒泡排序
    七大基本排序算法之选择排序
    七大基本排序算法之希尔排序
  • 原文地址:https://www.cnblogs.com/cwmizlp/p/9208291.html
Copyright © 2011-2022 走看看