新手上路之Hibernate(三):持久化對象三種狀態以及session的Get()與Load()區別

一、Hibernate持久化對象三種狀態

在Hibernate中持久化類的對象可以劃分爲三種狀態,分別是瞬態,持久態,脫管態。

1. 瞬態(Transient),也叫臨時態。處於這種狀態的對象具備的特徵如下:

               a) 不在Session的緩存中,不與任何的Session實例相關聯。


               b) 在數據庫中沒有與之相對應的記錄。

	User user = new User();
	user.setName("姓名");
	user.setAge("年齡");

2. 持久態(Persistent),處於這種狀態的對象具備的特徵如下:

                 a) 在Session的緩存中,與Session實例相關聯。


                 b) 在數據庫中存在與之相對應的記錄。

通過Session對象的save()方法進行保存處於瞬時態的對象後,該對象就變爲持久態。此時Session中已經存在該對象,並且對應數據庫中的一條記錄。

	SessionFactory sessionFactory = config.buildSessionFactory();  
	Session session = sessionFactory.getCurrentSession();  
	Transaction tx = session.beginTransaction();  
	User user = new User();  
	user.setName("姓名");
	user.setAge("年齡"); 
	session.save(user);  
	tx.commit(); 
在調用save()方法後,持久化對象user就變爲持久態,但是執行了commit()方法之後,數據庫操作纔會進行。

3. 脫管態(Detached),也叫遊離態。處於這種狀態的對象具備的特徵如下:

                   a) 不在Session的緩存中,不與任何的Session實例相關聯。


                   b) 在數據庫中存在與之相對應的記錄。(前提條件是沒有其他Session實例刪除該條記錄)。


這三種狀態之間是可以轉換的:


二、session的Get() 和 Load()區別

在Hibernate中,持久化對象的三種狀態是和Session的週期相關的,因爲Hibernate中的操作都是基於Session緩存機制完成的。所以Session對象的生命週期也關係着持久化對象的生命週期。那麼什麼是Session緩存機制呢?

Hibernate中的session緩存機制和會話session沒有一點關係,是完全不同的兩個概念。

Hibernate中引入session緩存的目的是:

               1、減少訪問數據庫的頻率,可以提高數據庫訪問的性能。

               2、保證緩存中的對象與數據庫中的相關記錄保持同步。

               3、當緩存中的持久化對象(位於緩存中的對象)之間存在循環關聯關係時,Sessioin會保證不出現訪問對象的死循環。

session有保存、更新、刪除、查詢方法。而對於查詢可以通過get和load兩種方式來獲取數據。下面就來說一下這兩種方式的區別。

Get():

	public void testGet1(){
		Session session = null;
		try{
			session = HibernateUntils.getSession();
			session.beginTransaction();
			User user=(User)session.get(User.class,"402898514099b934014099b936ca0003");
			System.out.println(user.getUsername());
			user.setUsername("TomNew");
			session.getTransaction().commit();
		}catch(Exception e){
			e.printStackTrace();
			session.getTransaction().rollback();
		}finally{
			HibernateUntils.closeSession(session);
		}
	}
設置斷點,Debug方式運行,有如下結果:



Load():

public void testLoad1() {
		Session session = null;
		try {
			session = HibernateUntils.getSession();
			session.beginTransaction();
			User user = (User)session.load(User.class, "402898514099b934014099b936ca0003");
			System.out.println(user.getUsername());
			user.setUsername("王五");
			session.getTransaction().commit();
		}catch(Exception e) {
			e.printStackTrace();
			session.getTransaction().rollback();
		}finally {
			HibernateUntils.closeSession(session);
		}
	}	

結果如下:


但是,此時的user並不爲空



通過對比我們可以看出:

執行get會馬上發出查詢語句。但是執行load不會馬上發出查詢語句,因爲load支持lazy(延遲加載)。只有真正使用這個對象的時候,再創建,對於hibernate來說才真正的發出查詢語句,主要是爲了提高性能。lazy是通過實現代理對象實現,代理對象主要採用的是CGLIB庫生成的,採用的是繼承方式。不同於JDK中的代理。


另外,這兩個方法的區別就是:如果查詢的數據爲空,那麼get方式返回null,而load方式會拋出ObjectNotFoundException異常

發佈了108 篇原創文章 · 獲贊 59 · 訪問量 106萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章