• 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操作)。

  • 相关阅读:
    个人技术总结——Flask-Admin扩展
    个人作业——软件工程实践总结&个人技术博客
    个人作业——软件评测
    结对第二次作业——某次疫情统计可视化的实现
    结对第一次—疫情统计可视化(原型设计)
    软工实践寒假作业(2/2)
    软工实践寒假作业(1/2)
    计算与软件工程 作业五
    计算与软件工程 作业四
    计算与软件工程 作业三
  • 原文地址:https://www.cnblogs.com/goloving/p/8268709.html
Copyright © 2020-2023  润新知