Hibernate中load()和get()的區別java
Hibernate中Session接口提供的load()和get()方法都是用來獲取一個實體對象,在使用方式和查詢性能上有一些區別,得到機制有所不一樣。綜合課堂和資料查閱總結以下:數據庫
若是使用get方法,hibernate會去確認該id對應的數據是否存在,它首先會去session中去查詢(session緩存其實就hibernate的一級緩存),若是沒有,再去二級緩存中去查詢,若是再沒有,就去數據庫中查詢,仍然沒有找到的話,就返回null緩存
而使用load方法的話,hibernate會認定該id對應的數據必定存在,它也會先去session緩存中去查找,session
若是沒有找到,hibernate會根據lazy屬性值來肯定是否使用延遲加載。若是lazy=‘true’ ,就使用延遲加載,返回該代理對象,ide
等到真正訪問到該對象的屬性時纔會去二級緩存中查詢,若是沒有,再去數據庫中查詢,若是尚未,就拋出org.hibernate.ObjectNotFoundException異常。性能
若是lazy='false' 則不使用延遲加載,這時load的訪問機制就和get同樣了。測試
課堂代碼舉例說明:spa
代碼演示 dao類: public interface IUserDao { public SysUserEntity findUserById(String id); }
Impl: (load()方法): public class UserDaoImpl implements IUserDao{ public SysUserEntity findUserById(String id) { Session session= HibernateSessionFactory.getSession(); //獲得持久狀態的對象 SysUserEntity user=(SysUserEntity)session.load(SysUserEntity.class,id); return user; } }
測試:(查找id爲1和100的用戶名,id爲1的存在,100不存在) //(id=」1」) public class Test { public static void main(String[] args) { IUserDao dao=new UserDaoImpl(); SysUserEntity user=dao.findUserById("1"); System.out.println(user.getUser()); } } 測試以下: Console: Hibernate: select sysuserent0_.userId as userId1_2_0_, sysuserent0_.loginPassWord as loginPas2_2_0_, sysuserent0_.loginUser as loginUse3_2_0_, sysuserent0_.user as user4_2_0_ from sys_user sysuserent0_ where sysuserent0_.userId=? 張三 //(id=」100」) public class Test { public static void main(String[] args) { IUserDao dao=new UserDaoImpl(); SysUserEntity user=dao.findUserById("100"); System.out.println(user); } } 測試以下: Hibernate: select sysuserent0_.userId as userId1_2_0_, sysuserent0_.loginPassWord as loginPas2_2_0_, sysuserent0_.loginUser as loginUse3_2_0_, sysuserent0_.user as user4_2_0_ from sys_user sysuserent0_ where sysuserent0_.userId=? Exception in thread "main" org.hibernate.ObjectNotFoundException: No row with the given identifier exists: [com.lovo.h.entity.SysUserEntity#100]
get()方法 public class UserDaoImpl implements IUserDao{ public SysUserEntity findUserById(String id) { Session session= HibernateSessionFactory.getSession(); //獲得持久狀態的對象 SysUserEntity user=(SysUserEntity)session.get(SysUserEntity.class,id); //關閉session HibernateSessionFactory.closeSession(); return user; } }
測試 //(id=」1」) public class Test { public static void main(String[] args) { IUserDao dao=new UserDaoImpl(); SysUserEntity user=dao.findUserById("1"); System.out.println(user.getUser()); } } 測試以下: Hibernate: select sysuserent0_.userId as userId1_2_0_, sysuserent0_.loginPassWord as loginPas2_2_0_, sysuserent0_.loginUser as loginUse3_2_0_, sysuserent0_.user as user4_2_0_ from sys_user sysuserent0_ where sysuserent0_.userId=? 張三 //(id=」100」) //(id=」100」) public class Test { public static void main(String[] args) { IUserDao dao=new UserDaoImpl(); SysUserEntity user=dao.findUserById("100"); System.out.println(user); } } 測試以下: Hibernate: select sysuserent0_.userId as userId1_2_0_, sysuserent0_.loginPassWord as loginPas2_2_0_, sysuserent0_.loginUser as loginUse3_2_0_, sysuserent0_.user as user4_2_0_ from sys_user sysuserent0_ where sysuserent0_.userId=? null
總之get和load的根本區別,hibernate對於load方法認爲該數據在數據庫中必定存在,能夠放心的使用代理來延遲加載,若是在使用過程當中發現了問題,只能拋異常;而對於get方法,hibernate必定要獲取到真實的數據,不然返回null。get方法首先查詢session緩存,沒有的話查詢二級緩存,最後查詢數據庫;反而load方法建立時查詢session緩存,沒有就建立代理,實際使用數據時才查詢二級緩存和數據庫。hibernate