hibernate的session在加载一个java对象时,可以将与这个 对象相关联的其他java对象都加载到缓存中,以便程序及时调用。但有些情况下,我们不需要加载太多无用的对象到缓存中,一来这样会撑爆内存,二来,增加了访问数据库的次数,所以为了合理的使用缓存,hibernate提供了几种检索策略来供用户选择。
1、立即检索策略
2、延迟检索策略
3、左外连接检索策略
4、程序中显示指定左外连接检索策略
当运行query的list()方法,如果采用立即检索策略,hibernate将先查询CUSTOMERS表中所有的记录,然后根据每条记录的ID,再到ORDRS表中查询相关联的记录,hibernate将依次执行以下select语句:
select * from CUSTOMRES;
select * from ORDERS where CUSTOMER_ID=1;
select * from ORDERS where CUSTOMER_ID=2;
select * from ORDERS where CUSTOMER_ID=3;
select * from ORDERS where CUSTOMER_ID=4;
根据以上可以看出
立即检索策略的缺点:
1、select语句的数目太多,需要频繁的访问数据库,会影响检索性能。如果需要查询n个CUSTOMER对象,那么必须执行n+1次查询语句。这种检索策略没有利用SQL的链接查询
功能,例如以上5条select语句完全可以通过以下一条select语句来完成:select * from CUSTOMERS left outer join ORDERS on CUDTOMERS.ID=ORDERS.CUSTOMER_ID
2、在应用逻辑只需要访问CUSTOMER对象,而不需要访问Order对象的场合,加载Order对象完全是多余的操作,这些多余的Order对象会白白浪费了许多内存空间。
所以 hibernate推出了延迟检索策略
1、采用延迟检索策略,只加载类本身,不加载关联类。直到第一次调用关联对象时,才会加载关联对象
2、在一对多关联关系中,对于<set>元素,应该优先考虑延迟检索策略:
<set name="oeders" inverse="true" lazy="true"> // lazy 表示是否使用延迟检索策略 true 表示使用
此时运行:
Customer customer =(Customer) session.load (Customer.class,new Long(1));
仅立即检索Customer 对象,执行以下select语句:
select * from CUSTOMERS where ID=1;
3、当应用程序第一次访问Customer 对象的order 变量时,例如调用
customer.getOrders().iterator()方法时,HIbernate才会执行以下select语句初始化当前Customer对象的orders变量,在初始化过程中,Hibernate才回到数据库中检索所有与Customer关联的Order对象
select * from ORDERS where CUSTOMER_ID=1;
延迟检索策略优缺点及使用场景
优点:
由程序决定加载哪些类和内容,避免了大量无用的SQL语句和内存消耗
缺点:
在session关闭后,就不能访问关联类对象了。需要确保在Session.close()方法前,调用关联对象。
适用范围
一对多或者多对多关联关系,应用程序不需要立即访问或者根本不会访问关联 的对象时。
左外连接欸检索策略
1、采用左外连接检索,能够使用sql的外链接查询,将需要加载的关联对象加载在缓存中。
2、如果把Order.hbm.xml文件的<mant-to-one>元素的fetch属性设为join,则使用左外连接检索策略。
3、对于一下代码:
Order order =(Order)session.load(Order.class,new Long(1));
在运行session.load()方法时,Hibernate执行以下select语句:
select * from ORDERS left outer join CUSTOMERS on ORDERS.CUSTOMER_ID =CUSTOMERS_ID where ORDERS.ID=1
左外连接检索策略
优点:
1、对应用程序完全透明,不管对象处于持久化状态,还是游离状态,应用程序都可以方便的从一个对象导航到与他关联的对象。
2、使用了外链接,select语句数量减少。
缺点:
1、可能会加载应用程序不需要访问的对象,白白浪费许多内存空间。
2、复杂的数据库表链接也会影响检索性能。
适用范围:
1、多对一或者一对一关联
2、应用程序需要立即访问对象
3、数据库系统系有良好的表连接性能
4、在映射文件中设定的检索策略是固定的,要么为延迟检索,要么为立即检索,要么为左外连接检索。
5、但应用逻辑是多种多样的,有些情况下需要延迟检索,而有些情况下需要外联结检索。
6、Hibernate 允许在应用程序中覆盖映射文件中设定的检索策略,由应用程序在运行时决定使用那种检索策略。