1. 程式人生 > >Hibernate學習筆記(二) — 探索 hibernate 中物件的狀態

Hibernate學習筆記(二) — 探索 hibernate 中物件的狀態

一、hibernate中物件的狀態有三種:

臨時、遊離和持久化,三種狀態轉化的方法都是通過session來呼叫的

什麼是持久化?

通俗的講,就是瞬時資料(比如記憶體中的資料,是不能永久儲存的)持久化為持久資料(比如持久化至資料庫中,能夠長久儲存)

二、三種狀態的相互轉換

session方法

session.save():該方法可以把一個物件從臨時裝填轉換成持久化狀態

session.get():從資料庫中根據主鍵提取出一個物件,該物件就是一個持久化狀態的物件

session.update():把一個物件變為持久化物件

session.evict():把一個持久化狀態的物件變為脫管狀態

session.clear():把所有Hibernate中的持久化狀態的物件變為脫管狀態的物件


三、測試session的各個方法

public class SessionfatoryTest {
	SessionFactory factory;
	Session session ;
	Transaction transaction;
	@Before
	public void init(){
		factory =  HibernateUtils.getSessionFactory();
		session = factory.openSession();
		transaction = session.beginTransaction();
	}
	
	/**
	 * 把一個臨時物件變為持久化物件
	 */
	@Test
	public void testSave(){
		User user = new User();
		user.setAge(11);
		user.setName("aaaa");
		session.save(user);
	}
	
	@Test
	public void testGet(){
		User user = (User) session.get(User.class, 1);
		System.out.println(user);
	}
	
	@Test
	public void testUpdate(){
		User user = (User) session.get(User.class, 1);
		user.setAge(102);
		//session.update(user);
		//因為user本身就是持久化物件,所以即使不寫session.update(),在
		//transaction.commit()時也會發出SQL語句,因為該物件的資料與
		//hibernate中的該物件的快照(副本)不一致,在flush()時,就會發出sql
	}
	
	@Test
	public void testUpdate2(){
		
		User user = (User) session.get(User.class, 1);
		session.evict(user);//脫管狀態
		user.setAge(100);
		session.update(user);//變為持久化狀態
	}

	@After
	public void destory(){
		transaction.commit();
		session.close();
		factory.close();
	}
}

四、Hibernate物件的副本(快照)


每次進行transaction.commit()時,都會進行flush操作,進而進行物件與副本的資料對比,決定是否傳送sql語句,比如取出的user的age是10,又改為10,user.setAge(10);那麼這樣是不會發送sql語句的。

session.flush()

實際上sql的傳送時刻,發生在session.flsuh(),在transaction.commit()之前,如果有session.flush()操作,就會發送sql語句,而不再等待transaction.commit().


session.flush()做了哪些事?

在hibernate內部,回去檢查所有的持久化物件

1.如果持久化物件是由臨時狀態轉換過來的就發出 insert 語句

2.如果持久化物件是由 get 等方法得到的

3.再次檢視副本,如果與副本對照後,一致就不傳送sql,如果不一致,就發生update語句

這也就是為什麼,不使用session.update() 同樣可以傳送 update 語句