Hibernate學習_007_get()與load()的區別

當要從數據庫中加載一個對象的時候,我們常常會使用兩個方法,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方法。




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章