一、瞬時狀態(Transient):
使用new操做符初始化的對象就是瞬時狀態,沒有跟任何數據庫數據相關聯;
二、持久化狀態(Parsistent):
若是對象與Session對象關聯起來,且該對象對應到數據庫記錄,則稱該對象處於持久化狀態。
三、遊離狀態(Detached)
Session被關閉或調用了Session的evict或clear方法把它從Session中移除了,則該對象脫離了Session的管理,持久化狀態變成遊離狀態,這表示該對象不在和數據庫保持同步,不受hibernate管理。html
Transient:瞬時狀態的對象只存在於內存中。
Parsistent:持久狀態的對象分別存在於內存、session對象、數據庫之中。
Detached:遊離狀態的對象存在於內存、數據庫之中,但不在session對象中。java
1)瞬時對象(Transient)git
new 建立 (無->Transient) ,即:對象經過構造方法成爲瞬時態;github
2)持久對象(Persistent)sql
1.1)get/load (無->Persistent),即:對象能夠由session的load或get方法直接成爲持久態;數據庫
get經過類名和id從數據庫讀取指定記錄,無匹配記錄返回null。
load經過類名和id從數據庫讀取指定記錄,無匹配記錄拋ObjectNotException異常。緩存
1.2)save/saveOrUpdate/persist (Transient->Persistent) ,即:瞬時態對象能夠經過save,saveOrUpdate或persist方法成爲持久態;session
1.3)update/saveOrUpdate(Detached->Persistent),即:遊離態對象則能夠經過update,saveOrUpdate成爲持久態;工具
3)遊離對象(Detached)spa
遊離態只能由持久態轉換而來(Persistent->Detached),經過close、clear、evict方法實現。
evict--把某個對象從session中移除,變爲遊離態;
clear--把全部對象從session中移除,對象所有變爲遊離態;
close--關閉session,其中的對象所有變爲遊離態;
一、get 與 load
都是從數據庫中加載數據封裝爲java對象,直接變爲持久態;
二、save,update與saveOrUpdate
save是將瞬時態轉爲持久態;
update是將遊離態轉爲持久態;
saveOrUpdate能夠說是二者的綜合,它執行時先判斷對象的狀態(主要是經過有無主鍵判斷的),如果自由態,則save,如果遊離態,則update;
三、save與persist
二者都是將對象由瞬時態轉爲持久態,但返回值不一樣:save返回主鍵值,而persist不返回;
package com.demo.test; import org.hibernate.Session; import org.junit.Test; import com.demo.Utils.HibernateUtil; import com.demo.pojo.User; public class SessionTest { @Test public void saveTest() { Session session = null; User user = null; try { session = HibernateUtil.currentSession(); session.beginTransaction(); //建立瞬時狀態對象 user = new User(); user.setName("東方不敗"); user.setPwd("123456"); //user還是一個瞬態對象 //持久狀態,user被session管理,而且id有值 -- oid //此時user已變成 持久態對象 session.save(user); //在持久狀態下髒數據檢查:當提交事務,清理緩存時發現session中的數據與數據庫的數據不一致時,會把session的數據更新到數據庫 //保存之後,再修改對象,會產生多條sql語句,效率下降,因此在save前修改數據 user.setName("西方求敗"); session.getTransaction().commit(); }catch (Exception e) { e.printStackTrace(); }finally { HibernateUtil.closeSession(); } //close、clear、evict方法都會使持久態對象 變成 遊離狀態 -- user user.setName("令狐沖"); try { session = HibernateUtil.currentSession(); session.beginTransaction(); //update使對象變成 持久狀態 session.update(user); session.getTransaction().commit(); }catch (Exception e) { e.printStackTrace(); }finally { HibernateUtil.closeSession(); } } @Test public void getTest() { Session session = null; try { session = HibernateUtil.currentSession(); //get後變爲持久狀態 //get方法會當即查詢該對象:範圍(查詢不到去下一級查詢)從session -> sessionFactory ->數據庫 //get方法找不到對象,不會有異常,返回nul User user = session.get(User.class, 7L); System.out.println(user.toString()); User user2 = session.get(User.class, 17L); System.out.println(user2); }catch (Exception e) { e.printStackTrace(); }finally { HibernateUtil.closeSession(); } } @Test public void loadTest() { Session session = null; try { session = HibernateUtil.currentSession(); //load後變爲持久狀態(這裏加載機制與get不一樣,稍後我會單獨寫一篇文章 介紹 get與load 的區別) //對象不存在時,拋出異常 User user = session.load(User.class, 7L); System.out.println(user.toString()); User user2 = session.load(User.class, 17L); System.out.println(user2.toString()); }catch (Exception e) { e.printStackTrace(); }finally { HibernateUtil.closeSession(); } } @Test public void clearTest() { Session session = null; User user = null; try { session = HibernateUtil.currentSession(); session.beginTransaction(); user = session.get(User.class,7L); System.out.println(user.getName()); session.getTransaction().commit(); session.clear(); //遊離狀態,不被session管理,數據庫不會被更改 user.setName("任我行"); System.out.println(user.getName()); }catch (Exception e) { e.printStackTrace(); }finally { HibernateUtil.closeSession(); } } @Test public void updateTest() { Session session = null; User user = null; try { session = HibernateUtil.currentSession(); session.beginTransaction(); //瞬時狀態 //手動構造對象 也能夠修改,可是須要指定全部的屬性值,不然,不設置的對象會置空,不建議這樣update數據 /*user = new User(); user.setId(7L); user.setName("盈盈"); session.update(user);*/ //通常這樣修改 //先去查詢 user = session.get(User.class,7L); if(user != null) { user.setName("盈盈"); session.update(user); } session.getTransaction().commit(); }catch (Exception e) { e.printStackTrace(); }finally { HibernateUtil.closeSession(); } } @Test public void deleteTest() { Session session = null; User user = null; try { session = HibernateUtil.currentSession(); session.beginTransaction(); //瞬時狀態 //手動構造一個對象,指定主鍵是能夠刪除數據的,不建議這樣搞 /*user = new User(); user.setId(7L); session.delete(user);*/ //應該這樣刪除數據 //從數據先加載該對象,而後刪除,能夠避免異常 user = session.get(User.class, 7L); if(user != null) { session.delete(user); } session.getTransaction().commit(); }catch (Exception e) { e.printStackTrace(); }finally { HibernateUtil.closeSession(); } } }
PS:源碼地址 https://github.com/JsonShare/hibernate-demo