當調用session.save(user)的時候,user對象會放到session裏,此時處於持久狀態
當提交事務的時候,user對象纔會存到DB中
當調用session.close的時候,user對象會從session中出來,此時處於脫管狀態
三種狀態對象的區別:標準就是與session,與數據庫的關係
瞬時狀態:與session,數據庫無關
持久狀態:在session裏,在數據庫裏,當持久化狀態對象發生改變的時候,hibernate會檢測到
問題一:當調用了session.save(User)後,又調用了user.setName(「張三」),hibernate會自動檢測到user對象的變化,問題是,hibernate是什麼時候通知數據庫的呢?
答案是,在commit的時候。由於他不會根據程序調用一次set,就同步一次數據庫,他會盡量的減小與數據庫就交互,會在commit()以前一次性的同步數據庫。
脫管狀態:與session無關,但在數據庫裏有數據。
何時用update()?
當對象處於脫管狀態的要想更新對象則調用update()、
當對象處於瞬時狀態的時候,則調用save()方法
問題是,在寫代碼的時候,怎麼知道狀態是處於瞬時和脫管狀態呢,一個好的方法是
當不知道對象處於什麼狀態的時候,調用saveOrUpdate方法,讓hibernate本身去判斷。那麼hibernate是怎麼判斷的呢,他也是根據對象的id或者Version來判斷,當id=0的時候,對象處於瞬時狀態。當id>0的時候,對象處於脫管狀態。那麼若是主鍵是String類型呢,則他會根據是否爲Null來判斷
三種狀態的轉變及調用什麼方法能夠轉變?
經過new能夠建立一個瞬時狀態的對象
經過save()或者saveOrUpdate()把瞬時狀態變成持久化狀態
經過delete()方法把持久化狀態變成瞬時狀態
經過evict()/close()/clear()把持久化狀態變成脫管狀態
經過update()/savaOrUpdate()/lock()方法把脫管狀態變成持久化狀態
經過get()或者load()或者find()或者iterate()等都能取得持久化狀態的對象
理解這幾種狀態的含義及使用,是很是有用的,只有明白了,在開發中才知道何時用什麼方法。 數據庫
-----------------------------------------------華麗分割線-----------------------------------------------緩存
Hibernate中有兩個極爲類似的方法get()與load(),他們均可以經過指定的實體類與ID從數據庫中讀取數據,並返回對應的實例,但Hibernate不會搞兩個徹底同樣的方法的,它們間的不一樣在於:session
1.若是找不到符合條件的紀錄,get()方法將返回null.而load()將會報出ObjectNotFoundEcception.ide
2.load()方法能夠返回實體的代理類實例,而get()永遠只返回實體類.hibernate
3.load()方法能夠充分利用二級緩存和內部緩存的現有數據,而get()方法只在內部緩存中進行查找,如沒有發現對應數據將跳過二級緩存,直接調用SQL完成查找.代理