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 語句