Hibernate
提供了
3
种检索策略:
l
延迟检索;
l
立即检索;
l
迫切左外连接;
Hibernate
提供
2
种方式来确定检索策略,一中是在配置文件当中,另外一种是在程序种设置。当然,如果你在程序中设置了检索策略,那么你在配置文件中的设置也就无效了。另外的一种情况是
HQL
会忽略配置文件的设置,而总是采用迫切左外连接。
一、
类级别的检索
可以选择的检索策略是立即检索和延迟检索,默认的是立即检索。用配置文件中的
<class>
节点的
lazy
来控制。
注意:不管你在配置
class
的
lazy
是
true
还是
false
,对
get()
和
create
Criteria
()
方法都不起作用,只有对
load()
方法起作用。
当你使用的检索策略是
lazy
的时候,当你执行
Customer customer = (Customer)session.load(Customer.class,new Long(1));
的时候,
Hibernate
不从数据库检索数据,而只是产生一个代理类,只有当你执行
Customer.getName();
的时候,
Hibernate
才到数据库取数据。所以,如下的代码是会被抛出异常的:
Session session
=
sessionFactory.openSession();
transaction tx
=
null
;
tx
=
session.beginTransaction();
Customer customer
=
(Customer)session.load(Customer.
class
,
new
Long(
1
));
tx.commit();
session.close();
customer.getName();
get()
方法总是用的立即检索,如果和它相关联的类也是用的立即检索,那么也会把相关联的数据也检索出来。
二、
一对和多对多关联检索
一般地,为了有减少对数据库的访问,我们往往用延迟检索的策略。所以,我们优先使用如下方式;
<set class=”order” inverse=”true’ lazy=”true” >
但是,我们在检索“多”的一方的时候,
Hibernate
不能为我们产生代理类。由此,我们就要用
betch-size
的配置来减少
SQL
语句。
当我们使用
outer-join
属性的时候,我们就没有必要使用
lazy
属性了。
Outer-join
会一次将“一”方和与之相关的“多”方用左外连接的方式检索出来。
Session session = sessionFactory.openSession();
Transaction tx = null;
tx = session.beginTransaction();
Customer customer = (Customer)session.get(Customer.class,new Long(1));
产生的
SQL
语句如下:
Hibernate: select customer0_.ID as ID1_, customer0_.NAME as NAME2_1_, orders1_.CUSTOMER_ID as CUSTOMER3_3_, orders1_.ID as ID3_, orders1_.ID as ID0_, orders1_.ORDER_NUMBER as ORDER2_1_0_, orders1_.CUSTOMER_ID as CUSTOMER3_1_0_ from sampledb.customers customer0_ left outer join sampledb.orders orders1_ on customer0_.ID=orders1_.CUSTOMER_ID where customer0_.ID=?