`

Session缓存和域对象在持久化层的三种状态

 
阅读更多

Session缓存:

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

 

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

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

tx = session.beginTransaction(); 
Customer c1=new Customer("zhangsan",new HashSet()); 

//Customer对象被持久化,并且加入到Session的缓存中 
session.save(c1);  
Long id=c1.getId(); 
//c1变量不再引用Customer对象 
c1=null;   

//从Session缓存中读取Customer对象,使c2变量引用Customer对象 
Customer c2=(Customer)session.load(Customer.class,id);  
tx.commit(); 

//关闭Session,清空缓存 
session.close(); 

//访问Customer对象 
System.out.println(c2.getName()); 
// c2变量不再引用Customer对象,此时Customer对象结束生命周期。 
c2=null;

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

tx = session.beginTransaction(); 
//第一次load会检索数据库,得到一个持久化的customer对象
Customer c1=(Customer)session.load(Customer.class,new Long(1));  
//第二次load,检查session缓存中有该对象,直接返回
Customer c2=(Customer)session.load(Customer.class,new Long(1));  
System.out.println(c1==c2);   // true or false ?? 
tx.commit(); 
session.close();

当缓存中持久化对象的状态发生了变化,Session并不会立即执行相关的SQL语句,这使得Session能够把几条相关的SQL语句合并为一条SQL语句,以便减少访问数据库的次数,从而提高应用程序的性能。

//以下程序代码对Customer的name属性修改了两次:
tx = session.beginTransaction(); 
Customer customer=(Customer)session.load(Customer.class, new Long(1)); 
customer.setName("Jack"); 
customer.setName("Mike"); 
tx.commit(); 
/*
当Session清理缓存时,只需执行一条update语句: 
update CUSTOMERS set NAME= 'Mike' ..... where ID=1;
*/

 总结Session缓存的作用:

(1)减少访问数据库的频率。应用程序从内存中读取持久化对象的速度显然比到数据库中查询数据的速度快多了,因此Session的缓存可以提高数据访问的性能。
(2)保证缓存中的对象与数据库中的相关记录保持同步。

 

在Hibernate中Java对象的状态:

临时状态(transient):刚刚用new语句创建,还没有被持久化,不处于Session的缓存中。处于临时状态的Java对象被称为临时对象。
持久化状态(persistent):已经被持久化,加入到Session的缓存中。处于持久化状态的Java对象被称为持久化对象。
游离状态(detached):已经被持久化,但不再处于Session的缓存中。处于游离状态的Java对象被称为游离对象。

 

对象状态转换图:

<!--[if gte mso 9]><xml><w:WordDocument><w:BrowserLevel>MicrosoftInternetExplorer4</w:BrowserLevel><w:DisplayHorizontalDrawingGridEvery>0</w:DisplayHorizontalDrawingGridEvery><w:DisplayVerticalDrawingGridEvery>2</w:DisplayVerticalDrawingGridEvery><w:DocumentKind>DocumentNotSpecified</w:DocumentKind><w:DrawingGridVerticalSpacing>7.8</w:DrawingGridVerticalSpacing><w:View>Normal</w:View><w:Compatibility></w:Compatibility><w:Zoom>0</w:Zoom></w:WordDocument></xml><![endif]-->

<!--[if gte mso 9]><xml><w:WordDocument><w:BrowserLevel>MicrosoftInternetExplorer4</w:BrowserLevel><w:DisplayHorizontalDrawingGridEvery>0</w:DisplayHorizontalDrawingGridEvery><w:DisplayVerticalDrawingGridEvery>2</w:DisplayVerticalDrawingGridEvery><w:DocumentKind>DocumentNotSpecified</w:DocumentKind><w:DrawingGridVerticalSpacing>7.8</w:DrawingGridVerticalSpacing><w:View>Normal</w:View><w:Compatibility></w:Compatibility><w:Zoom>0</w:Zoom></w:WordDocument></xml><![endif]-->

 

 


 

 

 

Customer对象的状态转换过程(第一段代码)
 

 

 

Session的update()方法完成以下操作:
(1)把Customer对象重新加入到Session缓存中,使它变为持久化对象。
(2)计划执行一个update语句。值得注意的是,Session只有在清理缓存的时候才会执行update语句,并且在执行时才会把Customer对象当前的属性值组装到update语句中。因此,即使程序中多次修改了Customer对象的属性,在清理缓存时只会执行一次update语句。 

Customer customer=new Customer(); 
customer.setName("Tom"); 
Session session1=sessionFactory.openSession(); 
Transaction tx1 = session1.beginTransaction(); 
session1.save(customer); 
tx1.commit(); 
session1.close(); 

//此时Customer对象变为游离对象 
Session session2=sessionFactory.openSession(); 
Transaction tx2 = session2.beginTransaction(); 
customer.setName("zhangsan"); //在和session2关联之前修改Customer对象的属性 
session2.update(customer); 
//此时Customer对象变为持久化对象
customer.setName("lisi"); //在和session2关联之后修改Customer对象的属性 
tx2.commit(); 
session2.close();

 客户层与业务逻辑层之间传递临时对象和游离对象的过程

 

 

 
 
 
 

 

  • 大小: 84.7 KB
  • 大小: 71.3 KB
  • 大小: 69.4 KB
  • 大小: 41.3 KB
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics