91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Hibernate與對象是怎么共事的

發布時間:2021-12-04 16:27:42 來源:億速云 閱讀:143 作者:iii 欄目:編程語言

本篇內容介紹了“Hibernate與對象是怎么共事的”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!

Hibernate是完整的對象/關系映射解決方案,它提供了對象狀態管理(state management)的功能,使開發者不再需要理會底層數據庫系統的細節。

也就是說,相對于常見的JDBC/SQL持久層方案中需要管理SQL語句,Hibernate采用了更自然的面向對象的視角來持久化Java應用中的數據。

換句話說,使用Hibernate的開發者應該總是關注對象的狀態(state),不必考慮SQL語句的執行。這部分細節已經由Hibernate掌管妥當,只有開發者在進行系統性能調優的時候才需要進行了解。

1. Hibernate對象狀態(object states)

Hibernate定義并支持下列對象狀態(state):

瞬時(Transient) - 由new操作符創建,且尚未與Hibernate Session 關聯的對象被認定為瞬時(Transient)的。瞬時(Transient)對象不會被持久化到數據庫中,也不會被賦予持久化標識(identifier)。如果程序中沒有保持對瞬時(Transient)對象的引用,它會被垃圾回收器(garbage collector)銷毀。使用Hibernate Session可以將其變為持久(Persistent)狀態。(Hibernate會自動執行必要的SQL語句)

持久(Persistent) - 持久(Persistent)的實例在數據庫中有對應的記錄,并擁有一個持久化標識(identifier)。 持久(Persistent)的實例可能是剛被保存的,或剛被加載的,無論哪一種,按定義對象都僅在相關聯的Session生命周期內的保持這種狀態。

Hibernate會檢測到處于持久(Persistent)狀態的對象的任何改動,在當前操作單元(unit of work)執行完畢時將對象數據(state)與數據庫同步(synchronize)。開發者不需要手動執行UPDATE。將對象從持久(Persistent)狀態變成瞬時(Transient)狀態同樣也不需要手動執行DELETE語句。

脫管(Detached) 與持久(Persistent)對象關聯的Session被關閉后,對象就變為脫管(Detached)的。對脫管(Detached)對象的引用依然有效,對象可繼續被修改。脫管(Detached)對象如果重新關聯到某個新的Session上, 會再次轉變為持久(Persistent)的(Detached其間的改動將被持久化到數據庫)。

這個功能使得一種編程模型,即中間會給用戶思考時間(user think-time)的長時間運行的操作單元(unit of work)的編程模型成為可能。 我們稱之為應用程序事務,即從用戶觀點看是一個操作單元(unit of work)。

接下來我們來細致的討論下狀態(states)及狀態間的轉換(state transitions)(以及觸發狀態轉換的Hibernate方法)。

2. 使對象持久化

Hibernate認為持久化類(persistent class)新實例化的對象是瞬時(Transient)的。我們可將瞬時(Transient)對象與session關聯而變為持久(Persistent)的。

DomesticCat fritz = new DomesticCat();  fritz.setColor(Color.GINGER);  fritz.setSex('M');  fritz.setName("Fritz");  Long generatedId = (Long) sess.save(fritz);

如果Cat的持久化標識(identifier)是generated類型的,那么該標識(identifier)會自動在save()被調用時產生并分配給cat。如果Cat的持久化標識(identifier)是assigned類型的,或是一個復合主鍵(composite key),那么該標識(identifier)應當在調用save()之前手動賦予給cat。 你也可以按照EJB3 early draft中定義的語義,使用persist()替代save()。

此外,你可以用一個重載版本的save()方法。

DomesticCat pk = new DomesticCat();  pk.setColor(Color.TABBY);  pk.setSex('F');  pk.setName("PK");  pk.setKittens( new HashSet() );  pk.addKitten(fritz);  sess.save( pk, new Long(1234) );

如果你持久化的對象有關聯的對象(associated objects)(例如上例中的kittens集合)那么對這些對象(譯注:pk和kittens)進行持久化的順序是任意的(也就是說可以先對kittens進行持久化也可以先對pk進行持久化),除非你在外鍵列上有NOT NULL約束。 Hibernate不會違反外鍵約束,但是如果你用錯誤的順序持久化對象(譯注:在pk持久之前持久kitten),那么可能會違反NOT NULL約束。

通常你不會為這些細節煩心,因為你很可能會使用Hibernate的傳播性持久化(transitive persistence)功能自動保存相關聯那些對象。 這樣連違反NOT NULL約束情況都不會出現了Hibernate會管好所有的事情。傳播性持久化(transitive persistence)將在本章稍后討論。

3. 裝載對象

如果你知道某個實例的持久化標識(identifier),你就可以使用Session的load()方法 來獲取它。 load()的另一個參數是指定類的.class對象。 本方法會創建指定類的持久化實例,并從數據庫加載其數據(state)。

Cat fritz = (Cat) sess.load(Cat.class, generatedId);  // you need to wrap primitive identifiers  long pkId = 1234;  DomesticCat pk = (DomesticCat) sess.load( Cat.class, new Long(pkId) );

此外, 你可以把數據(state)加載到指定的對象實例上(覆蓋掉該實例原來的數據)。

Cat cat = new DomesticCat();  // load pk's state into cat  sess.load( cat, new Long(pkId) );  Set kittens = cat.getKittens();

請注意如果沒有匹配的數據庫記錄,load()方法可能拋出無法恢復的異常(unrecoverable exception)。 如果類的映射使用了代理(proxy),load()方法會返回一個未初始化的代理,直到你調用該代理的某方法時才會去訪問數據庫。 若你希望在某對象中創建一個指向另一個對象的關聯,又不想在從數據庫中裝載該對象時同時裝載相關聯的那個對象,那么這種操作方式就用得上的了。 如果為相應類映射關系設置了batch-size, 那么使用這種操作方式允許多個對象被一批裝載(因為返回的是代理,無需從數據庫中抓取所有對象的數據)。

如果你不確定是否有匹配的行存在,應該使用get()方法,它會立刻訪問數據庫,如果沒有對應的行,會返回null。

Cat cat = (Cat) sess.get(Cat.class, id);  if (cat==null) {      cat = new Cat();      sess.save(cat, id);  }  return cat;

你甚至可以選用某個LockMode,用SQL的SELECT ... FOR UPDATE裝載對象。 請查閱API文檔以獲取更多信息。

Cat cat = (Cat) sess.get(Cat.class, id, LockMode.UPGRADE);

注意,任何關聯的對象或者包含的集合都不會被以FOR UPDATE方式返回, 除非你指定了lock或者all作為關聯(association)的級聯風格(cascade style)。

任何時候都可以使用refresh()方法強迫裝載對象和它的集合。如果你使用數據庫觸發器功能來處理對象的某些屬性,這個方法就很有用了。

sess.save(cat);  sess.flush(); //force the SQL INSERT  sess.refresh(cat); //re-read the state (after the trigger executes)

“Hibernate與對象是怎么共事的”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

汕头市| 河北省| 文化| 瓮安县| 景谷| 且末县| 广州市| 青冈县| 陈巴尔虎旗| 永和县| 城口县| 宣武区| 沅陵县| 塔城市| 台湾省| 贵溪市| 津市市| 双柏县| 林芝县| 临城县| 本溪市| 克东县| 安溪县| 古丈县| 蓬安县| 青海省| 扶绥县| 安阳市| 金溪县| 肃宁县| 竹北市| 广南县| 西华县| 军事| 荥经县| 宝丰县| 宁城县| 绥江县| 蒲江县| 大同市| 合川市|