读书人

fetch检索谋略

发布时间: 2012-12-28 10:29:04 作者: rapoo

fetch检索策略

fetch检索策略用来说明如何把关联对象加载上来!例如使用单独的select语句来加载关联对象;或者使用左外连接加载当前对象和关联对象。

?

单边检索策略 ??

?

? ? 在单边中设置fetch=join时,由于在加载当前对象时会同时加载关联对象,那么就不可能等到使用关联对象时才去加载关联对象。此时Hibernate使用左外连接加载当前对象和关联对象,这会使关联对象的lazy=true失效。? ?

? ? 这里我们使用Order和Customer来说明。其中一个Customer中可以有有多个Order,建立相应的实体类和.hbm.xml文件,在Order.hbm.xml中我们把<many-to-one>元素的fetch属性设置为join;

?

?

?

?下面是加载Order对象的测试代码:

?

String hql = "from Customer c where c.id in (1,2)";List<Customer> cList = session.createQuery(hql).list();for(Customer c : cList) {c.getName();Set<Order> orders = c.getOrders();orders.iterator();}

?结果为:

?

?

Hibernate: select customer0_.id as id0_, customer0_.name as name0_ from customer customer0_ where customer0_.id in (1 , 2)

Hibernate: select orders0_.customerid as customerid1_, orders0_.id as id1_, orders0_.id as id1_0_, orders0_.orderNumber as orderNum2_1_0_, orders0_.customerid as customerid1_0_ from orders orders0_ where orders0_.customerid=?

Hibernate: select orders0_.customerid as customerid1_, orders0_.id as id1_, orders0_.id as id1_0_, orders0_.orderNumber as orderNum2_1_0_, orders0_.customerid as customerid1_0_ from orders orders0_ where orders0_.customerid=?
?

结果分析:

1.在执行session.createQuery(hql).list()时,会执行一条SQL语句来加载两个Customer对象,但不会加载关联对象;

?

2.?在每次执行orders.iteraotr()时会执行一条SQL语句来加载当前Customer对象的关联对象。因为一共有两个Customer对象,所以会执行两条加载关联对象的SQL语句。

?

把<set>元素的fetch设置为subselect,再次执行上面的代码,结果如下:

?


Hibernate: select customer0_.id as id0_, customer0_.name as name0_ from customer customer0_ where customer0_.id in (1 , 2)

Hibernate: select orders0_.customerid as customerid1_, orders0_.id as id1_, orders0_.id as id1_0_, orders0_.orderNumber as orderNum2_1_0_, orders0_.customerid as customerid1_0_ from orders orders0_ where orders0_.customerid in (select customer0_.id from customer customer0_ where customer0_.id in (1 , 2))

?1.在执行session.createQuery(hql).list()时,会执行一条SQL语句来加载两个Customer对象,但不会加载关联对象。这与上面是一样的,没有什么区别

2.在第一次执行orders.iteraotr()时会执行一条子查询的SQL语句,它会一次性的加载当前List中所有Customer对象的关联对象。所以在下一次再执行orders.iteraotr()时就不会再执行SQL语句了

读书人网 >编程

热点推荐