域对象在持久化中的三种状态 (Hibernate Session)

摘自 圣思园hibernate17.自身双向一对多关联关系深入解析-28分钟开始

●教学内容
-Session的缓存的作用
-Session清理缓存的时间点
- 对象的临时状态,持久化状态和游离状态
-用Session的update()方法使游离态转变成持久化对象.


当Session的save()方法持久化一个User对象时,User对象被加入到Session的缓存中,以后即使应用程序中的引用变量不再引用该User对象, 只要Session的缓存还没有被清空,User对象仍然处于生命周期中。

当Session的load()方法试图从数据库中加载一个User对象时,Session先判断缓存中是否已经存在这个User对象,如果存在,就不需要再到数据库中检索。

三种状态的英文解释:
临时状态-transient:
an object is transient if it has been instantiated using the new operator, and it is not associated with a Hibernate Session. It has no persistent representation in the database and no identifer value has been assigned. Transient instances will be destroyed by the garbage collector if the application does not hold a reference anymore. Use the Hibernate Session to make an object persistent.
(我觉得这里的identifer

持久状态-persistent:
A persistent instance has an identifier value, a representation in the database and is associated with a Session. Hibernate will detect any changes made to an object in persistent state any synchronize the state with the database when the unit of work completes. Developers do not execute manual UPDATE statements, or DELETE statements when an object should be made transient.

游离态-detached:
A detached instance is an object that has been persistent, but its Session has been closed. The reference to the object is still valid, of course, and the detached instance might even be modified in this state. A detached instance can be reattached to a new Session at a later point in time, making it (and all the odifications) persistent again. This feature enables a programming model for long running units of work that require user think-time. We call them application transactions, i.e., a unit of work from the point of view of the user.

http://docs.jboss.org/hibernate/orm/3.3/reference/en/html/objectstate.html

用一个具体实例来看:

	public static void main(String[] args)
	{
		Session session = HibernateUtil.openSession();
		
		Transaction tx = null;

		tx = session.beginTransaction();
		
		
		User u1=new User(567,"hi",23); //transient state
		
	 	session.save(u1);   //persistent
		
		User u=(User) session.load(User.class, 567);
		System.out.println(u.getName());
		
		System.out.println(u==u1);
		
		
 
		
		session.close();
		
	 
	}



这里先实例了一个对象User, id是567, name是hi。
此时我们的数据库对象里面已经有了这一列。

由于在执行load之前, session里面已经有了id为567的user对象, 所以在
User u=(User) session.load(User.class, 567);
这里hibernate不会像数据库发送sql请求。

再看看:System.out.println(u==u1);
该代码返回结果为true。

这个结果说明了两点:
1. session里面此时已经包含了这个User对象,如图所示:



2. 当执行load方法时, hibernate会直接查找session中的Entity对象,正好有id为567的User类对象, 于是把该对象引用的内存地址返回, 不再查询数据库。



===================Session的缓存的作用============
1. 减少访问数据库的频率。 应用程序从内存中读取持久化对象的速度显然比到数据库中查询数据的速度快多了,因此Session的缓存可以提高数据访问的性能。
2. 保存缓存中的对象与数据库中的相关记录保持同步。 当缓存中持久化对象的状态发生了变化,Session并不会立即执行相关的SQL语句, 这使得Session能够把几条相关的SQL语句合并为一条SQL语句, 以便减少访问数据库的次数, 从而提高应用程序的性能。

Session清理缓存的时间点
-当应用程序调用org.hibernate.Transaction的commit()方法的时候, commit()方法先清理缓存,然后再向数据库提交事务. 如图:







- 当应用程序显式调用Session的flush()方法的时候.



========================
最后附上一张图说明对象的三种状态






猜你喜欢

转载自alleni123.iteye.com/blog/1977132