1、Mybatis级联分为哪些种类?如何使用?
2、简述级联使用中的N-1问题和延迟加载
Mybatis级联有2种,下面是分类及使用:
1、一对一关联
MyBatis中使用association标签来解决一对一的关联查询,association标签可用的属性如下:
property:对象属性的名称
javaType:对象属性的类型
column:所对应的外键字段名称
select:使用另一个查询封装的结果
2、一对多关联
MyBatis中使用collection标签来解决一对多的关联查询,ofType属性指定集合中元素的对象类型。
级联中的N+1问题
N+1问题来源于数据库中常见的级联技术,即N个数据库表形成关联关系,当再增加一个关联表时,也就是N+1个级联关系,由于某些时候,我们并不需要加载数据库的所有数据,而是某一个数据库表中数据,这时Mybatis会自动加载所有表的数据,多执行几条无关sql语句,会造成数据库资源的浪费以及系统性能的下降,这就是级联表的缺点。
Mybatis本身给出解决N+1问题的方案,也就是在N+1个级联表的情况下,只加载需求的数据库表数据。这是互联网发展的需求,性能提升的途径。。
Mybatis 的加载延迟
Mybatis 支持延迟加载,我们希望一次性把常用的级联数据(针对association 和 collection)通过 SQL 直接查询出来,而对于那些不常用的级联数据不要取出,而是等待要用时才取出,这些不常用的级联数据可以采用延迟加载的功能。
在Mybatis 的 settings 配置中配置是否加载延迟:
<setting>
<setting name="lazyLoadingEnabled" value="true">
<setting name="aggressiveLazyLoading" value="false"> #为false启动按需加载
</setting>
选项 lazyLoadingEnabled 决定是否开启延迟加载,
而选项 aggressiveLazyLoading 为 true 的时候,一加载对象(任何一个属性)就会加载他的全部属性(如:调用User对象的任何一个属性的时候就为这个User对象加载它的 role 属性)。
为 false 的时候,就是按需加载,调用User对象 的 role属性时才会去数据库查询并加载它的 role 属性的数据。
此外, Mybatis 中 还有 fetchType 属性。它存在两个值。
eager:获得当前POJO 后立即加载对应的数据。
lazy:获得当前POJO后延迟加载对应的数据。
如:
<resultMap id="userRoleResults" type="sqlmapper.User">
<id property="id" column="id" />
<result property="username" column="username" />
<association property="role" column="userRole" fetchType="eager" select="sqlmapper.RoleMapper.getRoleById"/>
</resultMap>
这样就会初始化对象的时候就为这个对象加载它的 role 属性。改成 fetchType=“lazy” 则调用User 的 role属性时才会加载它的 role 属性的数据。
fetchType 属性会忽略全局配置项 lazyLoadingEnabled 和 aggressiveLazyLoading 的配置。