Hibernate 检索策略

xing00 2010-05-10

Hibernate的检索策略包括类级别检索和关联级别的检索。

类级别检索策略包括立即检索和延迟检索:

立即检索:

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

延迟检索策略:

类级别的默认检索策略。当需要加载一个持久化对象时,系统不会立即加载对象属性实例,而是仅初始化它的OID属性,这种策略占用的内存很少。

例如:

select*fromCUSTOMERSwhereID=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

例如:

Customercustomer=(Customer)session.get(Customer.class,newLong(1));

Setorders=customer.getOrders();

IteratororderIte=orders.iterator();

当执行get方法的时候,采用立即检索策略,Hibernate执行了一下语句:

select*fromCUSTOMERSwhereID=1;

select*fromORDERSwhereCUSTOMER_ID=1;

通过以上Select语句,Hibernate加载了一个Customer对象和与之关联的Order对象。

延迟检索策略:lazy为true

这是默认的并且应该优先考虑的检索策略。

<setname="orders"inverse="true"lazy="true"></set>

此时再运行session.get(Customer.class,newLong(1));时,仅加载Customer对象,Customer的orders属性引用一个没有初始化的集合代理类实例。

Setorders=customer.getOrders();

Iteratorit=orders.iterator();//此时orders集合代理类被初始化

迫切左外连接检索:fetch为join,lazy的值将被忽略

<setname="orders"inverse="true"fetch="join"></set>

当执行一下语句时:

Customercustomer=(Customer)session.get(Customer.class,newLong(1));

Hibernate会执行以下select语句:

select*fromCUSTOMERSleftouterjoinORDERSonCUSTOMER.ID=ORDERS.CUSTOMER_IDwhereCUSTOMERS.ID=1;

由select语句可知,该检索策略采用了SQL外连接的查询功能,优点在于减少了select语句的数目,同时又可以获取关联对象。缺点就是SQL语句的复杂度提高了,同时系统构建表连接也需要耗时操作。

相关推荐