Hibernate之持久化对象三种状态概述

目录

持久化对象三种状态

 瞬时态(transient)

 持久态(persistent)

 脱管态(detached)

三种状态区分

三种状态转换

瞬时态→其他状态

瞬时态→持久态:Session的save()或saveOrUpdate()方法

瞬时态→脱管态:为瞬时态对象设置持久化标识OID

持久态→其他状态

持久态→瞬时态:Session的delete()

持久态→脱管态:执行evict()、close()或clear()

脱管态→其他状态

脱管态→持久态:Session的update()、saveOrUpdate()以及lock()方法

脱管态→瞬时态:将脱管态对象的持久化标识OID设置为null

持久态对象能够自动更新数据库


持久化对象三种状态

Hibernate为了更好的管理持久化类,特将持久化类分成了三种状态。在Hibernate中持久化的对象可以划分为三种状态

  •  瞬时态(transient)

瞬时态也称为临时态或者自由态,瞬时态的实例是由new命令创建、开辟内存空间的对象,不存在持久化标识OID(相当于主键值),尚未与Hibernate Session关联,在数据库中也没有记录,失去引用后将被JVM回收。瞬时状态的对象在内存中是孤立存在的,与数据库中的数据无任何关联,仅是一个信息携带的载体

  •  持久态(persistent)

持久态的对象存在持久化标识OID,加入到了Session缓存中,并且相关联的Session没有关闭,在数据库中有对应的记录,每条记录只对应唯一的持久化对象,需要注意的是,持久化对象时在事物还未提交前变成持久态的

  •  脱管态(detached)

脱管态也称力离线态或者游离态,当某个持久化状态的实例与Session的关联被关闭时就变成了脱管态。脱管态对象存在持久化标识OID,并且仍然与数据库中的数据存在关联,只是失去了与当前Session的关联,脱管态对象发生改变时,Hibernate不能检测到

三种状态区分

customer对象由new关键词创建,此时还未与Session进行关联,它的状态称为瞬时态;在执行了session.save(customer)操作后,book对象纳入了Session的管理范围,这时的customer对象变成了持久态对象,此时Session的事务还没有被提交;程序执行完commit()操作并关闭了Session后,customer对象与Session的关联被关闭,此时customer对象就变成了脱管态

    @Test
    public void test(){
        Session session = HibernateUtil.openSession();
        Transaction trans = session.beginTransaction();
        
        Customer customer = new Customer();        //瞬时态对象:没有持久化标识OID,没有被session管理
        customer.setCust_name("mark");    
        
        Serializable id = session.save(customer); //持久态对象:有持久化标识OID,被session管理
        
        trans.commit();
        session.close();
        System.out.println(customer);  //脱管态对象:有持久化标识OID,没有被session管理
    }

三种状态转换

三种状态之间是可以相互转换的

 从上图可以看出,当一个对象被执行了new关键字创建后,该对象处于瞬时态;当对瞬时态对象执行Session的save()或saveOrUpdate()方法后,该对象将被放入Session的一级缓存,对象进入持久态;当对持久态对象执行evict()、close()或clear()操作后,对象进入脱管态;当直接执行Session的get()、load()、find()或iterate()等方法从数据库里查询对象时,查询到的对象也处于持久态;当对数据库中的记录进行update()、saveOrUpdate()以及lock()等操作后,此时脱管态的对象就过渡到持久态;由于瞬时态和脱管态的对象不再session的管理范围,所以会在一段时间后被JVM回收

saveOrUpdate()方法,可以无脑地将瞬时态或者脱管态转换成持久态,持久化对象的三种状态可以通过调用Session中的一系列方法实现状态间的转换

  • 瞬时态→其他状态

瞬时态→持久态:Session的save()或saveOrUpdate()方法

瞬时态→脱管态:为瞬时态对象设置持久化标识OID

瞬时态和托管态的区别就是OID有没有值,所以可以通过为瞬时态对象设置OID,使其变成托管态对象

Customer customer = new Customer();        //瞬时态:没有持久化标识OID,没有被session管理
           customer.setCust_id(1);                 //脱管态:有持久化标识OID,没有被session管理

  • 持久态→其他状态

持久态对象可以直接通过Hibernate中Session的get()、load()方法,或者Query查询从数据库中获得

持久态→瞬时态:Session的delete()

被删除的持久化对象,不建议再次使用

持久态→脱管态:执行evict()、close()或clear()

evict()方法用于清除一级缓存中某一个对象;close()方法用关闭Session,清除一级缓存;clear()方法用于清除一级缓存中的所有对象

  • 脱管态→其他状态

脱管状态无法直接获得,是由其他状态对象转换而来的

脱管态→持久态:Session的update()、saveOrUpdate()以及lock()方法

被删除的持久化对象,不建议再次使用

脱管态→瞬时态:将脱管态对象的持久化标识OID设置为null

瞬时态和托管态的区别就是OID有没有值,所以可以通过为脱管态对象设置OID为null,使其变成瞬时态对象

session.close();                              //脱管态:有持久化标识OID,没有被session管理
           customer.setCust_id(null);             //瞬时态:没有持久化标识OID,没有被session管理

持久态对象能够自动更新数据库

 持久态对象能够依赖Hibernate的一级缓存,来使持久态对象自动更新数据,不用手动调用update方法即可更新

	public void test() {
		Session session = HibernateUtil.openSession();
		Transaction trans = session.beginTransaction();
		
		//获得持久态对象
		Customer customer = session.get(Customer.class, 10L);// 持久态对象
		customer.setCust_name("mark");

//		session.update(customer); // 不用手动调用update方法就可以更新

		trans.commit();
		session.close();
	}

猜你喜欢

转载自blog.csdn.net/mmake1994/article/details/81507724