hibernate的load和get方法有感
今天有空看到了一篇討論hibernate 快取討論的帖子, 突然就對帖子裡面提到的:
get總是返回[實際物件]
load儘量返回[代理物件]
在2年前看過hibernate 3.1的中文參考文件, 後來工作了, 就沒再看過 hibernate 的相關東西和書了. 以前沒發現這個 "代理物件" 這個詞的, 可能我當時沒仔細看文件吧. 對於 "代理物件" 跟 "實際物件"(我覺得應該說是實體物件好點) 有什麼區別就有點在意了.
google 了一下" hibernate load get 區別", 看了其中的一篇文章:Hibernate裡load和get方法的區別
還好, 看到 hibernate延遲載入的原理與實現 這篇文章, 這位老兄真的很不錯呢, 文章有程式碼, 有圖片, 有說明, 有過程, 有論點. 這篇文章剛好是通過 load 方法來討論 hibernate 的延遲載入原理的. 雖然我沒有看過hibernate 的Session 的load 方法的原始碼, 但是文章裡面load 方法實現的思路應該是一樣的.
現在要說說我的直觀的理解了, get 方法返回的是一個跟資料庫對映的實體類物件, 如物件 userByGet(類為User); 而load 方法返回的是一個 userByLoad(類也為User,get方法實現不同) 的物件, 它的主鍵id 被賦值. (這裡就不囉嗦到代理類及其targetObject變量了,這樣就不直觀了)
就像 userByGet(id=1, name="user1", age=20) 和 userByLoad{id=1, name=null, age=null} , load 方法就是返回一個 new User(1) 的物件, 他不用去快取或資料庫查詢.
但是當你需要 userByLoad 物件的變數name 或 age的值的時候, 呼叫userByLoad 的 getName() 或getAge() 方法的時候, 你將會呼叫到 get 方法, 此時 userByLoad{id=1, name="user1", age=20}, get 方法只會被呼叫一次.
如果get 方法不能取得User 物件, userByLoad.getName() 將會丟擲 ObjectNotFoundEcception, 所以這個異常可不是 load 方法丟擲的呢.
總結下, 拋開代理物件,實體物件和從session, 從資料庫取值不說, get 就是直接返回一個有完整賦值的 User 物件; load 是先返回一個主鍵id 賦值的 User 物件, 如果需要知道這個 User 物件其他值的時候, 就用get 方法返回一個有完整賦值的 User 物件;
貌似如果你需要 User 的詳細資訊, 就用get 方法吧, 應該比 load 方法效率要高點. 至於快取方面, get 和 load 應該是一樣的處理方法.
如果是表跟表關聯關係的情況下,用load方法可以提高效能
以上純理論, 沒實踐過.