Hibernate 检索策略

Hibernate的检索策略包括类级别检索和关联级别的检索。
类级别检索策略包括立即检索和延迟检索:
立即检索:
立即加载检索方法指定的对象。如果程序加载一个持久化对象的目的是为了访问它的属性,可以采用立即检索策略。将<class 中的lazy设置为false。在默认情况下,load()方法是采用延迟检索策略加载持久化对象的,而get()方法是采用立即检索策略的。

延迟检索策略:
类级别的默认检索策略。当需要加载一个持久化对象时,系统不会立即加载对象属性实例,而是仅初始化它的OID属性,这种策略占用的内存很少。
例如:
select * from CUSTOMERS where ID=1;
当采用load()方法时(默认检索策略为延迟检索) ,Hibernate不会执行CUSTOMERS表的Select语句,仅返回Customers类的代理类的实例,这个代理类包含了Customers类的所有属性,但仅初始化OID属性,其他属性都为null,只有当我们调用getXXX()的时候,才会初始化代理类中其他属性实例。

关联级别检索策略包括立即检索策略、延迟检索策略和迫切左外连接检索
在映射文件中用<set 元素配置一对多关联或多对多关联关系。<set 元素里面有两个属性lazy和fetch属性。下面简单介绍lazy和fetch属性:
本例采用Customer和Order两个类关联,即一个Customer对应多个Order。
lazy:主要决定orders集合被初始化的时机,即是在加载Customer对象时候就初始化就初始化,还是在程序访问orders对象的时候才初始化。当lazy为false采用前者,当lazy为true时采用后者。
fetch:取值为select或subselect时,决定初始化orders集合时的查询语句的形式,如果取值为join,决定orders集合被初始化的时机。

立即检索:lazy为false
例如:
Customer customer=(Customer)session.get(Customer.class,new Long(1));
Set orders=customer.getOrders();
Iterator orderIte=orders.iterator();

当执行get方法的时候,采用立即检索策略,Hibernate执行了一下语句:
select * from CUSTOMERS where ID=1;
select * from ORDERS where CUSTOMER_ID=1;
通过以上Select语句,Hibernate加载了一个Customer对象和与之关联的Order对象。

延迟检索策略:lazy为true
这是默认的并且应该优先考虑的检索策略。
<set name="orders" inverse="true" lazy="true"></set>
此时再运行session.get(Customer.class,new Long(1));时,仅加载Customer对象,Customer的orders属性引用一个没有初始化的集合代理类实例。
Set orders=customer.getOrders();
Iterator it=orders.iterator();//此时orders集合代理类被初始化

迫切左外连接检索:fetch为join,lazy的值将被忽略
<set name="orders" inverse="true" fetch="join"></set>
当执行一下语句时:
Customer customer=(Customer)session.get(Customer.class ,new Long(1));
Hibernate会执行以下select语句:
select * from CUSTOMERS left outer join ORDERS on CUSTOMER.ID=ORDERS.CUSTOMER_ID where CUSTOMERS.ID=1;
由select语句可知,该检索策略采用了SQL外连接的查询功能,优点在于减少了select语句的数目,同时又可以获取关联对象。缺点就是SQL语句的复杂度提高了,同时系统构建表连接也需要耗时操作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值