• hibernate中持久化对象的生命周期(三态:自由态,持久态,游离态 之间的转换)


      在hibernate中有三种状态:瞬时态(Transient)、 持久态(Persistent)、脱管态(Detached)。处于持久态的对象也称为PO(Persistence Object),瞬时对象和脱管对象也称为VO(Value Object)。这三种状态也可以称作:临时状态、持久状态、游离状态。
    一、三种状态介绍:
    (1) 瞬时状态:
      由new操作符创建,且尚未与Hibernate Session关联的对象被认定为瞬时(Transient)的。

      瞬时(Transient)对象不会被持久化到数据库中,也不会被赋予持久化标识(identifier)。如果瞬时(Transient)对象在程序中没有被引用,它会被垃圾回收器(garbage collector)销毁。使用Hibernate Session可以将其变为持久(Persistent)状态。(Hibernate会自动执行必要的SQL语句)。
      瞬时状态的特点有:
      1、 与数据库中的记录没有任何关联,也就是没有与其相关联的数据库记录。
      2、 与Session没有任何关系,也就是没有通过Session对象的实例对其进行任何持久化的操作。

    User user=new User();      //user是一个瞬时对象,在数据库的表中是没有记录和该对象相对应的。和session没有关系。
    user.setName(“ddd”);
    user.setBirthday(new Date());
    
    session.save(user); //持久化状态

    (2) 持久状态:
      持久(Persistent)是实例在数据库中有对应的记录,并拥有一个持久化标识(identifier)。

      持久(Persistent)的实例可能是刚被保存的,或刚被加载的,无论哪一种,按定义,它存在于相关联的Session作用范围内。

      Hibernate会检测到处于持久(Persistent)状态的对象的任何改动,在当前操作单元(unit of work)执行完毕时将对象数据(state)与数据库同步(synchronize)。开发者不需要手动执行Update。将对象从持久(Persistent)状态变成瞬时(Transient)状态同样也不需要手动执行delete语句。
      持久对象具有如下特点:
      1、 和session实例关联;
      2、 在数据库中有与之关联的记录。
      3、 Hibernate会根据持久态对象的属性的变化而改变数据库中的相应记录。
      举例:

            Session session = factory.openSession();    
            Transaction tx = session.beginTransaction();    
       
            session.save(stu); // persistent持久化状态    
            System.out.println(stu);    
       
            tx.commit();    
            session.close();    //执行close()方法之后,就会由持久对象转换成脱管对象
       
            System.out.println(stu); // 脱管对象

    (3)脱管状态:
      与持久(Persistent)状态对象关联的Session被关闭后,对象就变为脱管(Detached)的。对脱管(Detached)对象的引用依然有效,对象可继续被修改。

      脱管(Detached)对象如果重新关联到某个新的Session上,会再次转变为持久(Transistent)的(在脱管Detached其间的改动将被持久化到数据库)。这个功能使得一种编程模型,即中间会给用户思考时间(user think-time)的长时间运行的操作单元(unit of work)。
      脱管对象拥有数据库的识别值,可通过update()、saveOrUpdate()等方法,转变成持久对象。
      脱管对象具有如下特点:
      1、 本质上与瞬时对象相同,在没有任何变量引用它时,JVM会在适当的时候将它回收;
      2、 比瞬时对象多了一个数据库记录标识值。
      3、 不在于Session相关联。
      4、 脱管对象一定是由持久态对象转化而来。

    总结:

      1、当一个对象被new了以后此对象处于瞬时态(Transient);
      2、然后对此对象执行session的save() 或者saveOrUpdate()方法后,此对象被放入session的一级缓存进入持久态.
      3、当再对此对象执行evict()/close()/clear()的操作后此对象进入游离态(Detached)
      4、游离态(Detached)和瞬时态(Transient)的对象由于没有被session管理会在适当的时机被java的垃圾回收站(garbage)回收.
      5、执行session的get()/load()/find()/iternte()等方法从数据库里查询的到的对象,处于持久态(Persistent).  
      6、当对数据库中的纪录进行update()/saveOrUpdate()/lock()操作后游离态的对象就过渡到持久态 
      7、处于持久态(Persistent)与游离态(Detached)的对象在数据库中都有对应的记录.
      8、瞬时态(Transient)与游离态(Detached)的对象都可以被回收可是瞬时态的对象在数据库中没有对应的纪录,而游离态的对象在数据库中有对用的纪录。

    二、游离对象和临时对象异同:

      两者都不会被Session关联,对象属性和数据库可能不一致;

      游离对象由持久化对象关闭Session而转化而来,在内存中还有对象,所以此时就变成游离状态了;
    三、Hibernate和SQL的关系:

      在操作了hibernate的方法,如save()等后,并没有直接生成sql语句去操作数据库,而是把这些更新存入Session中,只有Session缓存要被更新时,底层的sql语句才能执行,数据存入数据库;

      下面举例说明:
      1、Session.save(user)运行机理。
      (1)把User对象加入缓存中,使它变成持久化对象;
      (2)选用映射文件指定的标识生成ID;
      (3)在Session清理缓存时候执行:在底层生成一个insert sql语句,把对象存入数据库;
      注意:在你执行Session.save(user)后,在Session清理缓存前,如果你修改user对象属性值,那么最终存入数据库的值将是最后修改的值;此过程中ID不能被修改;
      2、Session.delete(user)运行过程。
      (1)如果user是持久化对象,则执行删除操作,同样底层数据库的执行条件是:在Session清理缓存时候;
      (2)如果user是游离对象:

      第一步:将user对象和Session关联,使之成为持久化对象;

      第二步:然后按照user是持久化对象的过程执行;

    四、三态之间的转换方法:

      如何成为自由态?

      对象通过构造方法成为自由态;

      持久态和游离态则通过session的delete方法成为自由态

      如何成为持久态?

      对象可以由session的load或get方法直接成为持久态;

      自由态对象可以通过save,saveOrUpdate或persist方法成为持久态;

      游离态对象则可以通过update,saveOrUpdate成为持久态

      如何成为游离态?

      游离态只能由持久态转换而来,通过close或clear方法实现。

    五、几种转换方法的对比:

      1、get 与load

      都是从数据库中加载数据封装为java对象,使得java对象从自由态直接变为持久态;

      但是有两点区别:

      (1)get返回对象可以为null,load返回值则始终不为null,找不到时会抛异常

      (2)get即时执行insert,而load则是在使用此对象时才执行insert

      2、save,update与saveOrUpdate

      save是将自由态转为持久态,而update是将游离态转为持久态,saveOrUpdate可以说是两者的综合,它执行时先判断对象的状态(主要是通过有无主键判断的),若是自由态,则save,若是游离态,则update

      3、save与persist

      两者都是将对象由自由态转为持久态,但返回值不同:save返回主键值,而persist不返回

      4、saveOrUpdate与merge

      两者都是将自由态或游离态对象与数据库关联,但merge不改变对象的原有状态

      此外,对clear与flush方法也作介绍。

      clear是将session中的对象全部变为游离态,是对象由持久态变为游离态的一种方法(另外一种是关闭session);

      flush方法时为了使update操作能即时进行(正常情况下,只有在事务关闭时才进行update操作)。

  • 相关阅读:
    Python Revisited Day 13 (正则表达式)
    Python Revisited Day 06 (面向对象程序设计)
    Python Revisited (变量)
    Python Revisited Day 05(模块)
    Python Revisited Day 04 (控制结构与函数)
    Python Revisited Day 03 (组合数据类型)
    Numpy
    Python Revisited Day 01
    Python3使用openpyxl读写Excel文件
    Python3操作YAML文件
  • 原文地址:https://www.cnblogs.com/goloving/p/8268709.html
Copyright © 2020-2023  润新知