MyBatis的延迟加载
问题:在一对多的关系中,例:有一个班级,其中有 100 个学生,在查询班级的时候要不要把关联的学生查询出来,查询学生的时候要不要把关联的班级查询出来?
解答:在查询班级的时候,学生的信息应该是什么时候使用什么时候去查询,在查询学生时,班级的信息应该是随着学生查询时一起查询出来。
一、延迟加载
-
概念:MyBatis 中的延迟加载也称为懒加载,是指在进行表的关联查询时,按照设置延迟规则推迟对关联对象的 select 查询。在真正使用数据的时候才发起查询,不用的时候不查询关联的数据,延迟加载又叫做按需查询。例如,在进行一对多查询的时候,只查询出一方,当程序中需要多方数据时,MyBatis 在发出 sql 语句进行查询,这样子延迟加载就可以减少数据库压力,MyBatis 的延迟加载只是对关联对象的查询有延迟设置,对于主加载对象都是直接执行查询语句的。
-
MyBatis 中延迟加载的条件:resultMap 可以实现高级映射,例:使用 association、collection 实现一对一及一对多映射,association、collection 具备延迟加载功能。
-
延迟加载的好处:先从单表查询,需要时再从关联表查询,大大提高数据库性能,因为查询单表比关联查询多张表速度要快。
-
使用场景:在对应的四种关系表中,一对多、多对多通常情况下采用延迟加载,多对一、一对一、通常采用立即加载。
-
延迟加载的应用要求:关联对象的查询与主加载对象的查询必须是分别进行的 select 语句,不能是使用多表连接所进行的 select 查询,因为多表连接查询,实质是对一张表的查询,对由多个表连接后形成的一张表的查询,会一次性将多张表的所有信息查询出来。
二、开启延迟加载功能
MyBatis 中实现查询方法的延迟加载,在 MyBatis
的配置文件中通过设置 settings 的 lazyLoadingEnabled 属性为 true 进行开启全局的延迟加载,通过 aggressiveLazyLoading 属性开启立即加载。
设置名 | 描述 | 有效值 | 默认值 |
---|---|---|---|
lazyLoadingEnabled | 延迟加载的全局开关,当开启时所有关联对象都会延迟加载,特定关联关系可以通过设置 fetchType 属性来覆盖该项的开关状态。 | true|false | false |
aggressiveLazyLoading | 开启时,任一方法的调用都会加载该对象的所有延迟加载属性。 否则,每个延迟加载属性会按需加载(参考 lazyLoadTriggerMethods)。 | true|false | false(在 3.4.1 及之前的版本默认值为 true) |
lazyLoadTriggerMethods | 指定对象的哪些方法触发一次延迟加载。 | 用逗号分隔的方法列表。 | equals,clone,hashCode,toString |
<settings>
<!-- 开启延迟加载主要是前两个配置 -->
<!-- 延迟加载, 默认是 false-->
<setting name="lazyLoadingEnabled" value="true" />
<!-- 当为 true 时,所有延迟属性都会立即加载,为 false 时,调用这些延迟属性时才会查询和加载 -->
<setting name="aggressiveLazyLoading" value="false" />
<!-- 最好配置为空,这样可以最大限度延迟加载 -->
<!-- 当前配置的意思为当调用 getId 时延迟加载 -->
<!-- 可以不配置 -->
<setting name="lazyLoadTriggerMethods" value="getId"/>
</settings>
三、延迟加载的实现
-
在 resultMap 中使用 association 或者 collection,即可使用延迟加载。
-
延迟加载需要多个 select 语句,不能是一条多表连接的 select 语句。
实现班级学生案例:
- 创建实体类 班级类以及学生类
- 创建 StudentMapper 和 ClazzMapper 接口
- 创建 ClazzMapper.xml 和 StudentMapper.xml
- 测试:
当注释掉第 4 句时,因为没有要求查找学生,按照延迟加载的特性,程序只会查询班级的信息,而不会查询学生的信息,所以只有一条 sql 语句,就是根据班级编号查找班级的 select,并没有查找学生的 select:
当放开第四句时,因为 clazz.getStudents() 需要 student 数据,所以会执行第二条 sql 语句将 student 的信息查询到:
EOF
本文链接:https://www.cnblogs.com/zbh355376/p/14986307.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!