Hibernate session.get session.load

版权声明:转载时请以超链接形式标明文章原始出处和作者信息及本声明
http://solecjj.blogbus.com/logs/58078340.html

Hibernate中Session.load/get方法均可以根据指定的实体类和id从数据库读取记录,并返回与之对应的实体对象。其区别在于:

1.get()方法直接返回实体类,load()方法可以返回实体的代理类实例。

2.hibernate load是采用延迟机制(当lazy属性为true时) 而hibernate get不采用延迟机制(get语句马上读库)

3.找不到符合条件的数据 get方法将返回null load将会报出ObjectNotFoundExcepion

延迟加载:Hibernate尽量延迟向数据库发送sql,它自己有一个缓冲区,先把sql放在里面,最后一起发送,减少网络开销和数据库开销。



load方法原理:

当对象.hbm.xml配置文件元素的lazy属性设置为true时,调用load()方法时则返回持久对象的代理类实例,此时的代理类实例是由运行时动态生成的类,该代理类实例包括原目标对象的所有属性和方法,该代理类实例的属性除了ID不为null外,所在属性为null值,查看日志并没有 Hibernate SQL输出,说明没有执行查询操作,当代理类实例通过getXXX()方法获取属性值时,Hiberante才真正执行数据库查询操作。

注意:StudentEh s=(StudentEh)session.load(StudentEh.class,10);System.out.println(s.getId());

这两条语句同样不会产生sql语句,因为session.load后会在hibernate的一级缓存里存放一个map对象,该map的key就是id的值,但是当你getId()时,它是从一级缓存里取map的key值,而不去执行数据库查询。

当对象.hbm.xml配置文件元素的lazy属性设置为false时,调用load()方法则是立即执行数据库并直接返回实体类,并不返回代理类。而调用get()方法时不管lazy为何值,都直接返回实体类。

get方法原理:

get方法,hibernate会确认一下该id对应的数据是否存在,首先在session缓存中查找,然后在二级缓存中查找,还没有就查数据库,数据库中没有就返回null。



get方法如果在session缓存中找到了该id对应的对象,如果刚好该对象前面是被代理过的,如被load方法使用过,或者被其他关联对象延迟加载 过,那么返回的还是原先的代理对象,而不是实体类对象,如果该代理对象还没有加载实体数据(就是id以外的其他属性数据),那么它会查询二级缓存或者数据 库来加载数据,但是返回的还是代理对象,只不过已经加载了实体数据。

总结描述:

如果使用load方法,hibernate认为该id对应的对象(数据库记录)在数据库中是一定存在的,所以它可以放心的使用代理来延迟加载该对象。在用 到对象中的其他属性数据时才查询数据库,但是万一数据库中不存在该记录,那没办法,只能抛异常,所说的load方法抛异常是指在使用该对象的数据时,数据 库中不存在该数据时抛异常,而不是在创建这个对象时。由于session中的缓存对于hibernate来说是个相当廉价的资源,所以在load时会先查 一下session缓存看看该id对应的对象是否存在,不存在则创建代理。所以如果你知道该id在数据库中一定有对应记录存在就可以使用load方法来实 现延迟加载。

而对于get方法,hibernate一定要获取到真实的数据,否则返回null。

public Object load(String entityName, Serializable id)
throws HibernateException
{
LoadEvent event = new LoadEvent(id, entityName, false, this);
boolean success = false;
Object obj;
try
{
fireLoad(event, LoadEventListener.LOAD);
if(event.getResult() == null)
getFactory().getEntityNotFoundDelegate().handleEntityNotFound(entityName, id);
success = true;
obj = event.getResult();
}
finally
{
afterOperation(success);
}
return obj;
}



public Object get(String entityName, Serializable id)
throws HibernateException
{
LoadEvent event = new LoadEvent(id, entityName, false, this);
boolean success = false;
Object obj;
try
{
fireLoad(event, LoadEventListener.GET);
success = true;
obj = event.getResult();
}
finally
{
afterOperation(success);
}
return obj;
}



public static final LoadType GET = (new LoadType("GET")).setAllowNulls(true).LoadType.setAllowProxyCreation(false).LoadType.setCheckDeleted(true).LoadType.setNakedEntityReturned(false);

public static final LoadType LOAD = (new LoadType("LOAD")).setAllowNulls(false).LoadType.setAllowProxyCreation(true).LoadType.setCheckDeleted(true).LoadType.setNakedEntityReturned(false);

你可能感兴趣的:(Hibernate)