1 持久化對象三種狀態
瞬態:對象由new操作符創建,且尚未與Hibernate Session關聯的對象被認為處於瞬態。瞬態對象不會被持久化到數據庫中,也不會被賦予持久化標識。如果程序中失去了瞬態對像的引用,瞬態對象將被垃圾回收機制銷毀。使用Hibernate Session可以將其變為持久化狀態。
持久化:持久化實例在數據庫中有對應的記錄,並擁有一個持久化標識(identifier)。持久化的實例可以是剛剛保存的,也可以是剛被加載的。無論哪一種,持久化對象都必須與制定的Hibernate Session關聯。Hibernate會檢測到處於持久化狀態對象的改動,在當前操作完成時將對象數據寫回數據庫。開發者不需要手動執行UPDATE。
脫管:某個實例曾經處於持久化狀態,但隨着與之關聯的Session被關閉,該對象就變成托管狀態。脫管狀態的引用依然有效,對象可繼續被修改。如果重新讓脫管對象與某個Session關聯,這個脫管對象會重新轉換為持久化狀態,而脫管期間的改動也不會丟失,也可被寫入數據庫。正是因為這個功能,邏輯上的長事務成為可能,它被稱為應用程序事務。即事務可以跨越用戶的思考,因為當對象處於脫管狀態時,該對象的操作無須鎖定數據庫,不會造成性能的下降。
2 改變持久化對象狀態的方法
2.1 持久化實體——save & persist
讓瞬態轉變為持久化狀態,Hibernate Session提供了幾個方法:
- Serializable save(Object obj):將obj對象變為持久化狀態,該對象的屬性將被保存到數據庫。
- Serializable save(Object obj,Object pk):將obj對象保存到數據庫,保存到數據庫時,指定主鍵值。
- void persist(Object obj):將obj對象變為持久化狀態,該對象的屬性將被保存到數據庫。
- void persist(Object obj,Object pk):將obj對象變為持久化狀態,保存到數據庫時,指定主鍵值。
2.2 根據主鍵加載持久化實體——load
也可以通過load()方法來加載一個持久化實例,根據持久化類的標識屬性值加載持久化實例----其實質是從數據庫表加載一條新記錄。代碼如下:
News n = sess.load(News.class,New Integer(pk));
注意:如果沒有匹配的數據庫記錄,load()方法可能拋出HibernateException異常;如果在類映射文件(xxx.hbm.xml)中指定了延遲加載(lazy),則load()方法將會返回一個未初始化的代理對象,這個代理對象並沒有裝載數據記錄,直到程序調用該代理對象的某方法時,Hibernate才會去訪問數據庫。
load()方法和get()方法主要區別在於是否延遲加載:
① 使用load()方法具有延遲加載功能,load()方法不會立即訪問數據庫,當試圖加載的記錄不存在時,load()方法返回一個未初始化的代理對象;
② get()方法總是立即訪問數據庫,當試圖加載的記錄不存在時,get()方法將直接返回null。
2.3 更新游離狀態的實體——update & updateOrSave
對於一個曾經持久化的對象,但已經脫離了session的管理的脫管對象,Hibernate提供了update()、merge()、updateOrSave()等方法來保存這些修改。
① update(),使用該方法后脫管對象再次回到session 的管理下,變為持久化狀態;
② updateOrSave()方法,如果不清楚對象是否曾經被持久化過,使用此方法可以自動判斷,如果持久化過則update,沒有則save;
③ lock()方法也可以將某個對象重新持久化,但該脫管對象必須是沒有修改過的,代碼如下:
//簡單重新持久化 session.lock(news , LockMode.NONE); //先檢查持久化對象的版本,然后重新持久化對象 session.lock(news , LockMode.READ); //先檢查持久化對象的版本,然后使用SELECT...FOR UPDATE重新持久話對象 session.lock(news , LockMode.PESSIMISTIC_WRITE);
2.4 刪除持久化實體——delete
如果傳入的參數是持久化對象,Session就計划執行一個delete語句;如果傳入的參數是游離對象,先使游離對象被Session關聯,使它變為持久化對象,然后計划執行一個delete語句。一旦刪除該持久化對象,對應的數據庫記錄也將被刪除。
session.delete(n);
3 持久化操作的步驟
① 開發持久化類,由POJO+持久化注解組成
//② 創建Configuration對象,默認加載hibernate.cfg.xml文件。 Configuration conf=new Configuration().configure(); //③ 以Configuration對象創建SessionFactory對象的實例,它是產生Session對象實例的工廠,在整個應用中應該是唯一的。 SessionFactory sf=conf.buildSessionFactory(); //④ 創建Session對象,打開session(相當於JDBC獲得數據庫的連接) Session session=sf.openSession(); //⑤ 開始事務 Transaction tx=session.beginTransaction(); //⑥ 持久化操作(增刪改必須,查可選) session.save(user); //⑦ 提交事務 tx.commit(); //⑧ 關閉session,釋放數據庫的鏈接 session.close();
① 理解Session緩存原理 P514
② 延遲加載
③ HQL P476