zoukankan      html  css  js  c++  java
  • Hibernate中java对象的三种状态

    • 瞬时状态(Transient)

      通过new创建对象后,对象并没有立刻持久化,它并未与数据库中的数据有任何关联,此时Java对象的状态为瞬时状态。

      Session对于瞬时状态的Java对象是一无所知的,当对象不再被其他对象引用时,它的所有数据也就丢失了,对象将会被Java虚拟机按照垃圾回收机制处理。

    • 持久状态(Persistent)

      当对象与Session关联,被Session管理时,它就处于持久状态。处于持久状态的对象拥有数据库标识(数据库中的主键值)。

      那么,对象是什么时候与Session发生关联的呢?有两种方法:

        第一种,通过Sesison的查询接口,或者get()方法,或者load()方法从数据库中加载对象的时候,加载的对象是与数据库表中的一条记录关联的,此时对象与加载它的Session发生关联;

        第二种,瞬时状态的对象,通过Session的save()方法或SaveOrUpdate()方法时,Java对象也与Session发生关联。

      对于处于持久状态的对象,Session会持续跟踪和管理它们,如果对象的内部状态发生了任何变更,Hibernate会选择合适的时机(如事务提交时)将变更固化到数据库中。

    • 游离状态

      处于持久状态的对象,脱离与其关联的nSession的管理后,对象就处于游离状态。

      处于游离状态的对象,Session无法保证对象所包含的数据与数据库中的记录一直,因为Hibernate已经无法感知对该对象的任何操作。

      Session提供了两个方法(update()、merge()),将处于游离状态的对象,与一个新的Session发生关联。

      此时,对象的状态就从游离状态重新转换为持久状态。

    2.三种状态之间的转换:

    使用new关键字构件对象,该对象的状态是瞬时状态。

    1 .瞬时状态转为持久状态

      使用Session对象的save()或saveOrUpdate()方法保存对象后,该对象的状态由瞬时状态转换为持久状态。

      使用Session对象的get()或load()方法获取对象,该对象的状态是持久状态。

    2. 持久状态转为瞬时状态

      执行Session对象的delete()方法后,对象由原来的持久状态变为瞬时状态,因为此时该对象没有与任何的数据库数据关联。

    3. 持久状态转为游离状态

      执行了Session对象的evict()、clear()或close()方法,对象由原来的持久状态转为游离状态。

    4 .游离状态转为持久状态

      重新获取Session对象,执行Session对象的update()或saveOrUpdate()方法,对象由游离状态转为持久状态,该对象再次与Session对象相关联。

    5. 游离状态转为瞬时状态

      执行Session对象的delete()方法,对象由游离状态转为瞬时状态。

      处于瞬时状态或游离状态的对象不再被其他对象引用时,会被Java虚拟机按照垃圾回收机制处理。

    3.Hibernate中get()和load()区别

    当使用Session的get()方法时,如果加载的数据不存在,get()方法会返回一个NULL;但是使用load()方法,若加载的数据不存在,则会抛出异常。

    一.load加载方式

    当使用load方法来得到一个对象时,此时hibernate会使用延迟加载的机制来加载这个对象,即:当我们使用session.load()方法来加载一个对象时,此时并不会发出sql语句,当前得到的这个对象其实是一个代理对象,这个代理对象只保存了实体对象的id值,只有当我们要使用这个对象,得到其它属性时,这个时候才会发出sql语句,从数据库中去查询我们的对象。

     Session session = HibernateUtil.currentSession();
               Transaction tx=session.beginTransaction();
               Dept dept = (Dept)session.load(Dept.class,1);
               System.out.println(dept);
    通过load的方式加载对象时,会使用延迟加载机制,此时得到的User对象其实是一个
    代理对象,该代理对象里面仅仅只有id这个属性

    二、get加载方式

    相对于load的延迟加载方式,get就直接的多,当我们使用session.get()方法来得到一个对象时,不管我们使不使用这个对象,此时都会发出sql语句去从数据库中查询出来:

    Session session = HibernateUtil.currentSession();
               Transaction tx=session.beginTransaction();
    // 通过get方法来加载对象时,不管使不使用该对象,都会发出sql语句,
    //从数据库中查询
               Dept dept = (Dept)session.get(Dept.class,1);
               System.out.println(dept);

    因此我们可以看到,使用load的加载方式比get的加载方式性能要好一些,因为load加载时,得到的只是一个代理对象,当真正需要使用这个对象时再去从数据库中查询。

  • 相关阅读:
    Java实现 LeetCode 400 第N个数字
    Java实现 LeetCode 400 第N个数字
    Java实现 LeetCode 399 除法求值
    Java实现 LeetCode 399 除法求值
    Java实现 LeetCode 399 除法求值
    Java实现 LeetCode 398 随机数索引
    Java实现 LeetCode 398 随机数索引
    Java实现 LeetCode 398 随机数索引
    linux中的cd ..和cd -命令有什么区别?
    GCC使用
  • 原文地址:https://www.cnblogs.com/s1294/p/5798172.html
Copyright © 2011-2022 走看看