Session.load()、Session.get()相同点:
可以根据指定的实体类和id从数据库读取记录,并返回与之对应的实体对象。
Session.load()、Session.get()不同点(主要是性能不一样):
1. 对于get方法,get就比较简单粗暴,不管使不使用这个对象,都会直接发出SQL语句去数据库查询,数据库没有就返回null。
2. 对于load方法,hibernate会使用延迟加载的机制来加载这个对象,即此时并不会发出sql语句,当前得到的这个对象其实是一个代理对象,这个代理对象只保存了实体对象的id值,只有当我们要使用这个对象,得到其它属性时,这个时候才会发出sql语句,从数据库中去查询我们的对象。
而查找的顺序是:hibernate会确认一下该id对应的数据是否存在,首先在一级缓存(session)查找,没有就在二级缓存(SessionFactory)查找,没有就查询数据库,若仍没发现符合条件的记录,则会抛出一个ObjectNotFoundException。
Users user = (Users)session.load(Users.class,userId);
这句代码不会去执行数据库查询,不会执行任何SQL语句,只有用到user时才会去执行数据库查询。
Users user = (Users)session.get(Users.class, userId);
则立即去执行数据库查询。因此我们可以看到,使用load的加载方式比get的加载方式性能要好一些,因为load加载时,得到的只是一个代理对象,当真正需要使用这个对象时再去从数据库中查询。
3.注意了,这里get和load有两个重要区别:
如果未能发现符合条件的记录,get方法返回null,而load方法会抛出一个ObjectNotFoundException。
如果使用get方式来加载对象,之前说get返回null,所以当我们试图得到一个id不存在的对象时,自然会抛出NullPointException。
注意:
Users user = (Users)session.load(Users.class, userId);
System.out.println(user.getId());
上面这2句代码,不会去执行数据库操作。因为load后会在hibernate的一级缓存里存放一个map对象,userId的值充当map中的key,当你getId()时,它会去一级缓存里拿map的key值,而不去执行数据库查询。所以不会报任何错。不会执行任何数据库操作。(当然,不报错的前提是id必须实现了Java.io.Serializable接口,也就是可序列化的)。
总的来说:
get()----不支持LAZY
load()----支持LAZY