延迟加载
MyBatis 中的延迟加载,也称为懒加载,是指在进行关联查询时,按照设置延迟规则推迟对关联对象的 select 查询。延迟加载可以有效的减少数据库压力。
需要注意的是,MyBatis 的延迟加载只是对关联对象的查询有延迟设置,对于主加载对象都是直接执行查询语句的。
- 关联对象加载时机
MyBatis 根据对关联对象查询的 select 语句的执行时机,分为三种类型:直接加载、侵入式延迟加载与深度延迟加载。
① 直接加载:执行完对主加载对象的 select 语句,马上执行对关联对象的 select 查询。
② 侵入式延迟:执行对主加载对象的查询时,不会执行对关联对象的查询。但当要访问主加载对象的详情时,就会马上执行关联对象的 select 查询。即对关联对象的查询执行,侵入到了主加载对象的详情访问中。也可以这样理解:将关联对象的详情侵入到了主加载对象的详情中,即将关联对象的详情作为主加载对象的详情的一部分出现了。
③ 深度延迟:执行对主加载对象的查询时,不会执行对关联对象的查询。访向主加载对象的详情时也不会执行关联对象的 select 查询。只有当真正访问关联对象的详情时,才会执行对关联对象的 select 查询。
需要注意的是,延迟加载的应用要求,关联对象的查询与主加载对象的查询必须是分别进行的 select 语句,不能是使用多表连接所进行的 select 查询。因为,多表连接查询,其实质是对一张表的查询,对由多个表连接后形成的一张表的查询。会一次性将多张表的所有信息查询出来。
MyBatis 中对于延迟加载设置,可以应用到一对一、一对多、多对一、多对多的所有关联关系查询中。
下面以一对多关联关系查询为例,讲解 MyBatis 中的延迟加载应用。
项目:MyBatis_One2Many_2_lazy。在MyBatis_One2Many_2 的基础上修改。
直接加载
(1)修改主配置文件
在主配置文件的<properties/>与<typeAliases/>标签之间,添加<settings/>标签,用于完成全局参数设置。
在 MyBatis 帮助文档中 Ctrl + F 查询关键字 “lazy”,则可查询出延迟加载的相关参数名称及取值。
全局属性 lazyLoadingEnabled 的值只要设置为 false,那么,对于关联对象的查询,将采用直接加载。即在查询过主加载对象后,会马上查询关联对象。
lazyLoadingEnabled 的默认值为 false,即直接加载。
当然,对于标签的书写位置,是由约束文件进行规定好的,不能随便写。<configuration/>标签上点击 F2,可以查看它们的顺序即数量要求。
这些 Content Model 后所跟的一些符号,表示这些字标签在当前标签中可以包含的数量。常见的有:
① ?:表示子标签可以没有,若有的话,最多只能有一个。即小于等于 1。
② * :表示子标签可以没有,也可以有多个。即大于等于 0.
③ + :表示子标签最少要有一个。即大于等于1。
④ 没符号:表示有且只能有一个。即等于1。
(2)修改测试类
当程序执行到断点语句时,不仅对 country 表进行了查询,对 minister 表也同时进行了查询。
深度延迟加载
修改主配置文件的<settings/>,将延迟加载开关 lazyLoadingEnabled 开启(置为 true),将侵入式延迟加载开关 aggressiveLazyLoading 关闭(置为 false)。
其它代码均不作改变。此时运行会发现,只有当代码执行到输出 Minister 对象详情时,底层才执行了 select 语句对 minister 表进行查询。这已经将查询推迟到了不能再推的地步,故称为深度延迟加载。
侵入式延迟加载
修改主配置文件的<settings/>,将延迟加载开关 lazyLoadingEnabled 开启( 置为 true),将侵入式延迟加载开关 aggressiveLazyLoading 也开启(置为 true,默认为 true)。.
其它代码均不作改变。此时运行会发现,当代码执行断点处语句时会立即查询 country 表,但没未查询 minister 表。说明现在的延迟加载已经启动。
但继续执行下一语句,即对 Country 对象的详情进行访问时,对 minister 表也进行了查询。因为该延迟策略已经将主加载对象的关联属性值也作为主加载对象的基本信息了,而前面已经查询出了土加载对象的基本信息,但其关联对象基本信息尚无。所以,马上进行对 minister 表的查询。
换个角度来说,该延迟策略使关联对象的数据侵入到了主加载对象的数据中,所以称为侵入式延迟加载。
需要注意的是,该延迟策略也是一种延迟加载,需要在延迟加载开关 lazyLoadingEnabled 开启时才会起作用。者 lazyLoadingEnabled 为 false,则 aggressiveLazyLoading 无论取何值,均不起作用。
- 延迟加载策略总结
加载策略 lazyLoadingEnabled取值 aggressiveLazyLoading取值 直接加载 false false 深度延迟加载 true false 侵入式延迟加载 true true
网友评论