1.类级别的检索策略
1.1 类级别可选的检索策略包括立即检索和延迟检索, 默认为延迟检索
–立即检索: 立即加载检索方法指定的对象
–延迟检索: 延迟加载检索方法指定的对象。在使用具体的属性时,再进行加载
1.2 类级别的检索策略可以通过 <class> 元素的 lazy 属性进行设置
<class name="Customer" table="CUSTOMERS" lazy="false">
1.3 如果程序加载一个对象的目的是为了访问它的属性, 可以采取立即检索.
1.4 如果程序加载一个持久化对象的目的是仅仅为了获得它的引用, 可以采用延迟检索。注意出现懒加载异常!
1.5 无论 <class> 元素的 lazy 属性是 true 还是 false, Session 的 get() 方法及 Query 的 list() 方法在
类级别总是使用立即检索策略(只对load()方法有效)
1.6 若 <class> 元素的 lazy 属性为 true 或取默认值, Session 的 load() 方法不会执行查询数据表的 SELECT 语句,
仅返回代理类对象的实例, 该代理类实例有如下特征:
–由 Hibernate 在运行时采用 CGLIB 工具动态生成
–Hibernate 创建代理类实例时, 仅初始化其 OID 属性
–在应用程序第一次访问代理类实例的非 OID 属性时, Hibernate 会初始化代理类实例
public void testClassLeavle() {
Customer customer = (Customer) session.load(Customer.class, 1);
System.out.println(customer.getClass());
System.out.println(customer.getCustomerId());
System.out.println(customer.getCustomerName());
}
2 一对多和多对多的检索策略
2.1 在映射文件中, 用 <set> 元素来配置一对多关联及多对多关联关系. <set> 元素有 lazy 和 fetch 属性
–lazy: 主要决定 orders 集合被初始化的时机.
即到底是在加载 Customer 对象时就被初始化, 还是在程序访问 orders 集合时被初始化
@Test
public void testOnn2ManyLeavle() {
Customer customer = (Customer) session.get(Customer.class, 1);
System.out.println(customer.getCustomerName());
//1. 一对多,或多对多的集合属性默认使用懒加载
System.out.println(customer.getOrders().size());
//2.可以通过设置set的lazy属性来改变默认的检索策略,默认值为true。不建议修改
//3.lazy还可以设置为extra,增强的延迟检索,该取值会尽可能的延迟初始化的时机
}
2.2 <set> 元素的 batch-size 属性
•<set> 元素有一个 batch-size 属性, 用来为延迟检索策略或立即检索策略设定批量检索的数量.
批量检索能减少 SELECT 语句的数目, 提高延迟检索或立即检索的运行性能.
@Test
public void testBatchSize() {
List<Customer> customers = session.createQuery("FROM Customer").list();
System.out.println(customers.size());
for (Customer customer : customers) {
System.out.println(customer.getOrders().size());
}
//set元素的batch-size属性:设定一次初始化set集合的数量。
}
<set name="orders" table="ORDERS" batch-size="5">
<key column="CUSTOMER_ID"></key>
<one-to-many class="Order"/>
</set>