當要從數據庫中加載一個對象的時候,我們常常會使用兩個方法,load()方法和get()方法,這兩個方法雖然都可以取出數據庫中的數據,但是這兩個方法是有很大區別的。他們的區別主要表現在以下幾點:
第一:是否立即發出Sql語句。
使用get方式:
@Test
public void testSession() {
Session session = sf.getCurrentSession();
session.beginTransaction();
Teacher t = (Teacher)session.get(Teacher.class, 1);//使用get方式。
session.beginTransaction();
session.getTransaction().commit();
}
使用這種方式會立馬發出sql語句,馬上取出數據庫中的對象。Hibernate:
select
teacher0_.id as id1_0_,
teacher0_.name as name1_0_,
from
_Teacher teacher0_
where
teacher0_.id=?
使用load方式:@Test
public void testSession() {
Session session = sf.getCurrentSession();
session.beginTransaction();
Teacher t = (Teacher)session.load(Teacher.class, 1);//使用load方式
session.beginTransaction();
session.getTransaction().commit();
}
使用load方式,是不會立刻產生sql語句的。看下面這個實驗就會明白,使用load的時候,是真正在使用對象的時候纔會發出sql語句。
@Test
public void testSession() {
Session session = sf.getCurrentSession();
session.beginTransaction();
Teacher t = (Teacher)session.load(Teacher.class, 1);
System.out.println("此時還沒有發出Sql語句!!!!");
System.out.println("使用對象是,才發出SQL語句,對象的名字是:"+t.getName());
session.beginTransaction();
session.getTransaction().commit();
}
輸出結果:
此時還沒有發出Sql語句!!!!
Hibernate:
select
teacher0_.id as id1_0_,
teacher0_.birthDay as birthDay1_0_,
teacher0_.myWifeName as myWifeName1_0_,
teacher0_.name as name1_0_,
teacher0_.title as title1_0_,
teacher0_.zhicheng as zhicheng1_0_
from
_Teacher teacher0_
where
teacher0_.id=?
使用對象是,才發出SQL語句,對象的名字是:t1
從輸出結果可以看出,確實load不會立刻發出SQL查詢語句。
第二:這兩個方法的返回值不一樣。load返回的是代理對象(這個代理對象時真實類的子類。),而get方式返回的是真實類的對象。
load方法返回的是原來真實類的子類對象,也就是真實類的代理。
@Test
public void testSession() {
Session session = sf.getCurrentSession();
session.beginTransaction();
System.out.println(session.load(Teacher.class, 1).<span style="color:#ff0000;">getClass()</span>);
session.beginTransaction();
session.getTransaction().commit();
}
查看輸出:
class com.zxb.model.Teacher_$$_javassist1
從輸出我們可以看到,返回的並不是我們的Teacher類,而是一個加了後綴javassist的類,這個類就是一個代理類,javassist是java中專門生產代理和產生二進制代碼的一個類。 而當我們使用get方法的時候,我們就會發現,輸出的是真實類的對象,代碼輸出結果如下,測試代碼再次不給出,load換get即可。
class com.zxb.model.Teacher
第三:在數據庫中沒有要加載的數據項時,程序反映不一樣。
其實,這一點很好理解,load的時候,壓根就沒發出SQL語句查數據庫,所以就是數據不存在,也不會報錯,但真正在使用對象的時候,數據不存在,纔會發出lazyInitializationException,而get方法是立刻發出SQL語句,如果數據庫中不存在對應數據,則程序會立馬報錯。
綜上所述,爲了及時返現程序中的錯誤,我們在程序中一般使用get方法來加載數據。而不是使用load方法。