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方法。




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