1. 對於Hibernate get方法,Hibernate會確認一下該id對應的數據是否存在,首先在session緩存中查找,而後在二級緩存中查找,尚未就查詢數據庫,數據庫中沒有就返回null。數據庫
2. Hibernate load方法加載實體對象的時候,根據映射文件上類級別的lazy屬性的配置(默認爲true),分狀況討論:緩存
(1)若爲true,則首先在Session緩存中查找,看看該id對應的對象是否存在,不存在則使用延遲加載,返回實體的代理類對象(該代理類爲 實體類的子類,由CGLIB動態生成)。等到具體使用該對象(除獲取OID之外)的時候,再查詢二級緩存和數據庫,若仍沒發現符合條件的記錄,則會拋出一 個ObjectNotFoundException。session
(2)若爲false,就跟Hibernate get方法查找順序同樣,只是最終若沒發現符合條件的記錄,則會拋出一個ObjectNotFoundException。spa
舉例說明以下:hibernate
load加載方法:代理
Users user = (Users)session.load(Users.class, userId); 對象
get加載方法:get
Users user = (Users)session.get(Users.class, userId); 兩加載方法區別:io
區別1:若是數據庫中,沒有userId的對象。若是經過get方法加載,則返回的是一個null;若是經過load加載,則返回一個代理對象,若是後面代碼若是調用user對象的某個屬性(好比user.getPassword())會拋出異常:org.hibernate.ObjectNotFoundException;class
區別2:load支持延遲加載,get不支持延遲加載。
也就是說:
Java代碼
Users user = (Users)session.load(Users.class, userId);
這句代碼不會去執行數據庫查詢,只有用到user時纔會去執行數據庫查詢。
而:Java代碼
Users user = (Users)session.get(Users.class, userId);
則當即去執行數據庫查詢。
注意:Java代碼
Users user = (Users)session.load(Users.class, userId);
System.out.println(user.getId());
上面這2句代碼,不會去執行數據庫操做。由於load後會在hibernate的一級緩存裏存放一個map對象,該map的key就是userId的值,可是當你getId()時,它會去一級緩存裏拿map的key值,而不去執行數據庫查詢。因此不會報任何錯。不會執行任何數據庫操做。