SSH框架之Hibernate的查询优化(五)
第一节:Hibernate的抓取策略
1.1 什么是抓取策略
抓取策略是当应用程序需要在(Hibernate实体对象图)关联关系间进行导航的时候,Hibernate如何获取关联对象的策略。
Hibernate的抓取策略是Hibernate提升性能的一种手段,可以在获取关联对象的时候,对发送的语句进行优化,但是往往抓取策略需要和延迟加载一起使用来提示性能。则需要我们学习延迟加载的相关知识。
1.2 延迟加载
- 1.2.1 延迟加载的分类
延迟加载(Lazy load)是(也称为懒加载)Hibernate关联关系对象默认的加载方式,延迟加载机制是为了避免一些无谓的性能开销而提出来的,所谓延迟加载就是当在真正需要数据的时候,才真正执行数据加载操作。
通常将延迟加载分为两类:一类叫做类级别延迟,另一类叫做关联级别的延迟。类级别的延迟指的是查询某个对象的时候,是否采用延迟,这个通常在<class>标签上配置lazy属性。关联级别的延迟指的是,查询一个对象的关联对象的时候是否采用延迟加载。这个通常在<set>或<many-to-one>上配置lazy属性。
【类级别的延迟加载】
使用load方法检索某个对象的时候,这个类是否采用延迟加载的策略,就是类级别的延迟。类级别的延迟一般在<class>上配置lazy属性,lazy的默认值是true。默认是延迟加载的,所以使用load方法区查询的时候,不会马上发送SQL语句,当真正使用该对象的时候,才会发送SQL语句。
Customer customer = session.load(Customer.class,1L);
类级别的延迟加载一般我们不进行修改,采用默认值lazy=“true”就可以了。
【关联级别的延迟加载】
关联级别的延迟加载指的是查询到某个对象以后,检索他的关联对象的时候是否采用延迟加载。
Customer customer = session.get(Customer.class,1L);
Set<LinkMan> linkMans = customer.getLinkMans();
关联级别的延迟通常是在<set>和<many-to-one>上来配置的。
<set>标签上的lazy通常有三个取值:
- true:默认值,采用延迟加载
- false:检索关联对象的时候,不采用延迟加载。
- extra:极其懒惰的。
<many-to-one> - proxy:默认值,是否采用延迟加载取决于一的一方类上的lazy属性的值。
- false:检索关联对象的时候,不采用延迟加载。
- no-proxy:不常用
1.3 抓取策略
延迟加载和抓取策略一起使用提升开发的程序的性能。抓取策略指的是查询某个对象的时候,如何抓取其关联对象。这个也可以通过配置完成。在关联对象的标签上配置fetch属性。关联上就分为是在<set>和<many-to-one>上,也就有不同的取值。
<set>标签上的fetch通常有三个取值:
- select :默认值,发送的是普通的select语句查询。
- join:发送一条迫切左外连接去查询。
- subselect:发送一条子查询语句去查询其关联对象。
<many-to-one>标签上的fetch有二个取值:
- select :默认值,发送的是普通的select语句查询关联对象。
- join:发送一条迫切左外连接去查询其关联对象。
1.4 <set>集合上的fetch和lazy:
fetch:控制的是查询其关联对象的时候采用的SQL语句的格式。
* select :默认值,发送的是普通的select语句查询关联对象。
* join:发送一条迫切左外连接去查询关联对象。
* subselect:发送一条子查询语句去查询其关联对象。
lazy:控制的是查询其关联对象的时候是否采用延迟加载的策略。
* true:默认值,采用延迟加载
* false:检索关联对象的时候,不采用延迟加载。
* extra:极其懒惰的。
我们可以简单的总结一下fetch和lazy的作用,其实fetch主要控制抓取关联对象的时候发送SQL语句的格式。lazy主要控制查询其关联对象的时候是否采用延迟加载的。注意:当fetch属性设置为join时,lazy的设置失效。
1.5 批量抓取
批量抓取就是同时查询多个对象的关联对象的时候,可以采用批量抓取进行优化。实现批量抓取效果,可以通过配置batch-size属性来完成(了解即可)。