类级别可选的检索策略包括立即检索和延迟检索,默认为延迟检索。如果<class>元素的lazy属性为true,表示采用延迟检索;如果lazy属性为false,表示采用立即检索。lazy属性的默认值为true。对于类级别的检索策略只影响session的load()方法,对于session的get()方法和hql方法都是无效的。
说明:<1默认情况下session的load()采用延迟加载策略;session的get()和Query的list()或者unique()总是采用立即检索策略
<2当程序加载一个持久化对象的目的是为了访问它的属性,可以采用立即检索。如果程序加载一个持久化对象的目的是为了获得它的引用,可以采用延迟检索
<3.在默认的检索策略的情况下,session的oad()方法将会返回以代理,该代理只存在OID属性,当发出getXXX()获取除OID之外的属性时,hibernate才会真正的发出sql语句返回一个真正的对象
<4.无论是session的load()方法,get()方法或者是Query的list(),unique()方法。当加载“一”的一方的时候,如果“多”的一方采用的是延迟加载策略,那么他们都不会立即执行查询多的一方的select语句。注意load()方法,如果他所对应的“多”的一方采用的是立即检索的策略,此时他也不会把多的一方全部检索出来,除非发出一个除获取OID之外的getXXX()方法
<5. org.hibernate.Hibernate类的initialize()静态方法用于在session范围内显示初始化代理类对象,isInitialized()方法用于判断代理类实例是否已经被初始化。如以下代码,执行后不会出现人任何错误
Customer customer=(Customer)session.load(Customer.class,2);
if(!Hibernate.isInitialized(customer)){
Hibernate.initialize(customer);
}
tx.commit();
session.close();
System.out.println("sss:"+customer.getName());
}
关联级别的检索策略,关联级别的索引包括立即检索,延迟检索和迫切左外连接检索,他们会影响session的load()方法和get()方法,以及Query API和Criteria API;例外情况是Query API会忽略映射文件中设定的迫切左外连接
在映射文件中,用<set>元素来配置一对多关联及多对多关联关系。<set>元素有lazy和fetch属性
lazy属性:主要决定‘多’的一方的集合被初始化的时机,即到底是在加载‘一’的一方对象时就被初始化还是在程序访问‘多’的一方的集合时候被初始化
fetch属性:取值为“select”或“subselect”时,决定初始化‘多’的一方的集合时查询语句的形式;如果取值为‘join’则决定‘多‘的一方的集合被初始化的时机,
说明:假如没有显示设置lazy和fetch属性,那么采用默认的延迟检索策略。
如果把fetch的属性设置为join,那么lazy属性被忽略,此时显示设置lazy属性是无意义的
以下以Customer与order为例
一,立即检索(lazy的属性为false)
此时在加载“一”的的一端的对象时会把“多”的一端的所有对象的全部加载,这显示会浪费内存,因此在一对多关联级别中不能随意使用立即检索策略,要优先考虑默认的延迟检索策略
二,延迟检索(lazy的属性为true)
此时仅仅加载“一”的一端的对象Customer,Customer对象的orders属性引用一个没有初始化的集合代理类实例,换句话说此时orders集合中没有放任何order对象,由此可见,尽管Hibernate会延迟检索与Customer对象关联的order对象,但不会创建Order代理类实例。事实上,这时也无法创建Order代理类实例,因为无法知道与Customer关联的所有Order对象的OID,只有当orders集合代理类实例被初始化时,才会到数据库中检索所有与Customer关联的Order对象,
orders集合代理类实例化的时机
<1.当应用程序第一次访问它,例如调用它的iterator(),size(),isEmpty()或contains()方法,例如
Set orders=customer.getOrders();
Iterator it=orders.iterator(); // 导致orders集合代理类被实例化
<2.通过Hibernate.initialize()方法初始化它
Set orders=customer.getOrders();
Hibernate.initialize(orders); // 导致orders集合代理类被实例化