现在的位置: 首页 > 综合 > 正文

hibernate检索策略1

2014年01月27日 ⁄ 综合 ⁄ 共 3912字 ⁄ 字号 评论关闭
 

5.1 Hibernate的检索策略有:立即检索、延迟检索、迫切左外连接检索。

5.1.1  首先介绍一对多和多对多关系的检索策略

有两个表orderscustomers orderscustomers是多对一关系。Orders外键customer_id参照customers表的主键id,如下所示:

 

orders                          Customers

Id   order_id    customer_id                id   name

1     order1     1                                       1   tom

2     order2     1                                       2   peter

3     order3     2                                       3   kallen

 

在映射文件中,用<set>元素来配置一对多及多对多关联关系。

如:

  <set name=orders inverse=true >

     <key column=coustomer_id>

     <one-to-many class=mypack.order>

 </set>

以下代码通过sessionget()方法加载OID1Customer   对象.

tx = session.beginTransaction();

Customer customer = (Customer) session.get(Customer.class,new Long(1));

Set orders = customer.getOrders();

Iterator it = orders.iterator();

5.1.1.1  立即检索策略

执行sessionget方法时,如果采用立即检索策略,Hibernate会执行以下select 语句:

Select * from customers where id=1;

Select * from orders where customer_id=1;

通过以下select 语句,Hibernate加载了一个Customer对象和两个order对象.Customer对象的orders属性引用的是一个Hibernate提供的Set集合类实例,这个实例引用了两个order对象.现在,如果不需要orders表中的数据那么以上sql语句中,第二个语句就白白浪费了时间和内存。

5.1.1.2  延迟检索策略

对于set元素应该优生考虑延迟检索策略.

<set name=orders inverse=true lazy=true>(lazy的默认值是:false)

此时运行sessionget()方法时,立即检索Customer对象,不对order对象进行检索。仅执行以下select 语句:

select  *  form  customer  where  id=1

这样,在不需要orders表数据的情况下可以避免无谓的操作。此时,没有创建order实例,当需要时,Hibernate会初始化order对象。

5.1.1.3  批量延迟检索

<set>元素的batch-size 属性,用于为延迟检索或立即检索策略设定批量检索的数量。

lazy=true时,为批量延迟检索。

以下Sessionfind方法,用于检索所有的Customer对象:

tx = session.beginTransaction();

List customerLists = session.find(“from customer as c”);

Iterator it = customerLists.iterator();

Customer customer1 = (Customer)customerIterator.next();

Customer customer2 = (Customer)customerIterator.next();

Customer customer3 = (Customer)customerIterator.next();

 

Iterator orderIterator1 = customer1.getOrder().iterator();

Iterator orderIterator2 = customer2.getOrder().iterator();

Iterator orderIterator3 = customer3.getOrder().iterator();

 

sessionfind方法检索Customer对象时,仅立即执行检索Customer对象的select   语句. Select * from customers;

customers表中共有四条记录,因此,Hibernate将创建四个Customer对象,它们的orders属性各自引用一个代理类实例。

当执行 Iterator orderIterator1 = customer1.getOrder().iterator();  方法时,会初始化OID  1Customer对象的orders对象,Hibernate执行的select语句为:

Select * from orders where customer_id=1

 

当执行 Iterator orderIterator2 = customer2.getOrder().iterator();  方法时,会初始化OID  2Customer对象的orders对象,Hibernate执行的select语句为:

Select * from orders where customer_id=2。依次类推。由此可见,初始化三个orders集合类实例,Hibernate必须执行三条查询语句。为了减少select语句的数目,可以采用批量延迟检索,即设置<set>元素的batch-size属性:

<set name=orders inverse=true lazy=true batch-size=3>

这样,当访问Iterator orderIterator1 = customer1.getOrder().iterator()方法时, Session的缓存中共有三个orders集合类实例未被初始化,现在batch-size=3,因此会批量初始化三个orders集合类实例,Hibernate会执行的select的语句为:

Select * from orders where customer=1 or customer=2 or customer=3。当访问Iterator orderIterator2 = customer2.getOrder().iterator()时,不需要初始化它的orders集合类实例。

 

5.1.1.4   批量立即检索

对于find 方法,List customerLists = session.find(“from customer as c”);

orders集合默认为立即检索策略时,<set name=orders inverse=true>

find方法会立即执行以下语句:

select * from customers;

select * from orders where customer_id=1;

select * from orders where customer_id=2;

select * from orders where customer_id=3;

为了减少 select 语句数量,可以设置 set元素的batch-size属性。

: <set name=orders inverse=true batch-size=2>

此时,find方法会立即执行以下sql语句:

select * from customers;

select * from orders where customer_id=1 or customer_id=2;

select * from orders where customer_id=3;

batch-size=3,此时find()方法会立即执行以下sql语句:

select * from customers;

select * from orders where customer_id=1 or customer_id=2 or customer_id=3;

 

 

5.1.1.5   迫切左外连接检索

如果把outer-join设备true

:<set name=orders inverse=true outer-join=true”>

当执行customer = (Customer)session.get(Customer.class,new Long(1));

时,会执行以下sql语句:

Select * from customers left outer join orders on customer.id=orders.customer_id where customer.id=1;

值得注意的是:sessionfind方法,会忽略映射文件中配置的迫切左外连接,即使outer-join=true,当用List customer = session.find(“from customer as c”);时,

HibernateCustomer对象的orders 集合仍然采用立即检索策略,Hibernate会执行的select 语句为:

Select * from customer;

Select * from orders where customer_id=1;

Select * from orders where customer_id=2;

Select * from orders where customer_id=3;

抱歉!评论已关闭.