Hibernate中load()和get()的區別

Hibernateload()和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

  

  

總之getload的根本區別,hibernate對於load方法認爲該數據在數據庫中必定存在,能夠放心的使用代理來延遲加載,若是在使用過程當中發現了問題,只能拋異常;而對於get方法,hibernate必定要獲取到真實的數據,不然返回nullget方法首先查詢session緩存,沒有的話查詢二級緩存,最後查詢數據庫;反而load方法建立時查詢session緩存,沒有就建立代理,實際使用數據時才查詢二級緩存和數據庫。hibernate

相關文章
相關標籤/搜索