Hibernate检索优化

版权声明: https://blog.csdn.net/qq_42499188/article/details/84554737

对对象进行检索的目的是为了将对象加载到内存,让程序使用其数据。所以,对象检索也称为对象加载。直接通过 get()、load()等查询语句加载的对象,称为主加载对象,而主加载对象所关联的对象,称为关联加载对象,或从加载对象。根据检索对象的不同,可以将检索优化分为两类:
(1)当前对象检索优化
(2)关联对象检索优化

对于不使用优化进行对象检索的过程,称为直接加载;否则称为延迟加载,或懒加载

1、当前对象检索优化

对于当前对象进行检索,即对主加载对象进行检索。通常使用 Session 提供的两个方法:get()与 load()。默认情况下,get()为直接加载,而 load()为延迟加载。

get()方法的直接加载指,当代码中出现 get()时,后台马上会调用执行 select 语句,将对象直接加载到内存。

load()方法的延迟加载指,当代码中出现 load()时,后台并不会马上调用执行 select。只有当代码中真正要访问除了对象的主键 id 属性以外的其它属性时,即真正要访问对象的详情时,才会真正执行 select 语句,即此时才会将对象真正加载到内存。

为什么对id属性的访问不会引发select的执行?

因为对于 load()方法,第二个参数必须为要加载对象的 id,此值不用从 DB 中获取,直接从 load()参数即可获得。所以,对 id 属性的访问,不会引发 select 的执行。

当执行完load()后,系统都做了些什么?

当执行完load()后,系统会生成对象的代理对象,该代理对象进行了字节码增强。从该代理对象的属性 handler 的值可以看出两点:

Javaassist 名称部分,说明其进行了字节码增强。在 Hibernate 的 Jar 包中,required 目录下的 javassist-3.18.1-GA.jar 是 Java 字节码操作助手,可完成字节码增强。
LazyInitializer 名称部分,说明其采用了延迟加载技术。

当执行完load()后,handler属性的initialized属性值为false,说明该代理对象尚未被初始化。

当执行完对id的输出后,会立即输出id的值,此时,还未执行select。

当执行对对象其他属性输出时,就需要从DB中查询了。此时才会真正调用执行select,然后输出name的值。此时,再查看handler的initialized属性值,已由false变为了true。

get()与load()的另一个区别:当要检索的对象在DB中不存在时,get()方法返回值为null,而load()会抛出异常。

2、关联对象检索优化

对于关联对象的检索,也可进行延迟加载优化。,要依据映射文件的配置。映射文件中对于关联对象检索的优化配置属性有两个:lazy、fetch。这两个属性是对关联对象的检索进行优化,所以它们是设置在映射文件的关联属性映射中的。

lazy 与 fetch 各具有若干值,它们不同值的组合,表示不同的对象加载策略。根据这两个属性配置位置的不同,分为两种:

(1)多端加载优化
(2)单端加载优化

多端加载优化:所谓多端关联加载优化,是指一方为主加载对象,而多方作为从加载对象,对于多方加载时所进行的延迟加载优化配置。鉴于此,fetch、lazy 应设置在一方映射文件的关联属性中,即设置在集合<set/>标签之中。

lazy 用于指定对象加载时机,即何时加载问题。此时其取值有:false、true、extra。
fetch 用于指定对象加载方式,即如何加载问题,即采用哪种 select 查询,此时其取值有:join、select、subselect。

lazy取值 意义
lazy=“false” 直接加载
lazy=“true” 延迟加载
lazy=“extra” 特别延迟加载。执行聚合函数可以解决的,不进行详情查询
fetch取值 意义
fetch=“join” 采用迫切左外连接查询
fetch=“select” 采用普通select查询
fetch=“subselect” 采用子查询(Hibernate5 不支持该策略)

单端加载优化:所谓单端加载优化,是指多方为主加载对象,而一方作为从加载对象,对于一方加载时所进行的延迟加载优化配置。鉴于此 fetch、lazy 设置在多方映射文件的关联属性中,即<many-to-one/>标签中。

lazy 用于指定对象加载时机,即何时加载问题。此时其取值有:false、proxy、no-proxy。

fetch 用于指定对象加载方式,即如何加载问题,即采用哪种 select 查询,此时其取值有:join、select。

lazy取值 意义
lazy=“false” 直接加载
lazy=“proxy” 使用字节码代理。关联属性是否延迟加载,由该类的lazy值决定
lazy=“no-proxy” 不研究
fetch取值 意义
fetch=“join” 采用迫切左外连接查询
fetch=“select” 采用普通select查询

猜你喜欢

转载自blog.csdn.net/qq_42499188/article/details/84554737
今日推荐