当要从数据库中加载一个对象的时候,我们常常会使用两个方法,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方法。