关于对象的加载,Hibernate提供了load()和get()方法。
例子1:
@Test
public void testHibernateLazy01(){
Session session = null ;
try {
session = HibernateUtil.openSession() ;
User u = (User) session.load(User.class,1);
} catch (Exception e) {
e.printStackTrace();
} finally {
HibernateUtil.closeSession(session);
}
}
例子2:
@Test
public void testHibernateLazy01(){
Session session = null ;
try {
session = HibernateUtil.openSession() ;
User u = (User) session.get(User.class,1);
} catch (Exception e) {
e.printStackTrace();
} finally {
HibernateUtil.closeSession(session);
}
}
如上,例子1,2分别是Hibernate的两种简单的对象加载的方法,分别执行两个测试,得到下面的两个结果:
【get】
【load】
可以看出来,使用get()方法,后台是有sql打印出来的,而使用load()方法是没有sql打印出来的
而load()这种情况就是Hibernate的延迟加载,指的是仅仅完成load()操作之后并不会马上发出sql语句,只有在使用到该对象的时候才会发出sql,当完成load()之后,例子中的对象u其实就是一个代理对象,并且这个代理对象中只存储了对应的id这一个值。
所以如下代码,如果对上面的代码做如下修改?
【例子3:对应get()】
@Test
public void testHibernateLazy01(){
Session session = null ;
try {
session = HibernateUtil.openSession() ;
User u = (User) session.get(User.class,100);
System.out.println("要输出的id:"+u.getId());
} catch (Exception e) {
e.printStackTrace();
} finally {
HibernateUtil.closeSession(session);
}
}
【例子4:对应load()】
@Test
public void testHibernateLazy01(){
Session session = null ;
try {
session = HibernateUtil.openSession() ;
User u = (User) session.load(User.class,100);
System.out.println("要输出的id:"+u.getId());
} catch (Exception e) {
e.printStackTrace();
} finally {
HibernateUtil.closeSession(session);
}
}
上面这两种情况,因为load延迟加载已经存储了对应的id值,所以我们获取它的id值得时候是没有问题的。而get是要访问数据库从,数据库中取数据,所以就会抛出空指针异常。
然后当取user对象中的其他的值的时候,他们会抛出的异常信息?
例子,用两种加载的方法在获取id的时候在获取name的值(范例代码这里不写了)他们的执行结果?
【get方法】
【load方法】
可以看出,get方法因为在数据库中找不到对应的数据,所以一直抛出的是空指针异常,而load方法因为延迟加载代理对象的原因所以id值是可以获取到的,但是本身session中是没有这个对象的,所以当获取其他信息的时候还是找不到对应的对象。抛出一个“ObjectNotFoundException”
这就是延迟加载,只有在使用到对象的时候才会发sql。而get没有延迟加载。
观察下面的代码:
例子5:
【定义一个UserDaoImpl实现类】
public class UserDaoImpl {
public User load(int id){
Session session = null ;
User user = null;
try {
session = HibernateUtil.openSession() ;
user = (User) session.load(User.class, id);
} catch (Exception e) {
e.printStackTrace();
} finally {
HibernateUtil.closeSession(session);
}
return user ;
}
}
【junit代码】
@Test
public void testHibernateLazy02(){
UserDaoImpl userDao = new UserDaoImpl() ;
User user = userDao.load(1) ;
System.out.println("获取user的name"+user.getNickName());
}
【执行后的结果】
由于使用了load,load是有延迟加载的返回的时候的u是一个代理对象,仅仅只有一个代理对象,但是返回的时候session已经被关闭了,这时要获取这个user对象的其他属性的时候就需要去数据库取获取,但是这时session已经关闭了所以就会抛出“org.hibernate.LazyInitializationException: could not initialize proxy - no Session”,这就是使用延迟加载最大的一个问题,解决这个问题最简单的办法就是换成get去加载