mybatis之延迟加载
Mybatis配置文件中通过两个属性lazyLoadingEnabled和aggressiveLazyLoading来控制延迟加载和按需加载(是针对查询从表的时候延迟加载还是不延迟加载)
延迟加载:在真正使用数据的时候才发起查询,不用的时候不查询关联的数据,延迟加载又叫按需查询(懒加载)
立即加载:不管用不用,只要一调用方法,马上发起查询。
使用场景:在对应的四种表关系中,一对多、多对多通常情况下采用延迟加载,多对一、一对一通常情况下采用立即加载。
lazyLoadingEnabled:是否启用延迟加载,mybatis默认为false,不启用延迟加载。lazyLoadingEnabled属性控制全局是否使用延迟加载,特殊关联关系也可以通过嵌套查询中fetchType属性单独配置来覆盖该项的开关状态(fetchType属性值lazy或者eager)。
aggressiveLazyLoading:是否按需加载属性,默认值false,lazyLoadingEnabled属性启用时只要加载对象,就会加载该对象的所有属性;关闭该属性则会按需加载,即使用到某关联属性时,实时执行嵌套查询加载该属性。
SqlMapConfig.xml中修改配置,注册lazyLoadMapper.xml
<settings> <!-- 启用延迟加载特性,不配置默认关闭该特性--> <setting name="lazyLoadingEnabled" value="true"></setting> <!-- 按需加载: false:使用关联属性,及时加载; true,加载对象,则加载所有属性, --> <setting name="aggressiveLazyLoading" value="false"/> </settings> <mappers> <!-- 注册Mapper.xml文件 --> <mapper resource="mapper/lazyLoadMapper.xml"></mapper> </mappers>
运行测试
添加mapper接口
View Code测试方法
View Code运行程序查看sql执行记录:

当前配置:启用延迟加载lazyLoadingEnabled=true和按需加载aggressiveLazyLoading=false
Step1: 执行Mapper方法lazyLoadTest,实际只执行了select * from category where id=#{id}
Step2: 执行System.out.println(category.getName()),加载属性,由于启用按需加载aggressiveLazyLoading=false,name属性此前已加载好,所以此处无数据库交互
Step3: 执行category.getProductList().size(),加载属性productList,按需加载需要执行延迟加载sql脚本select * from products where categoryid=#{id},与数据库交互
将aggressiveLazyLoading属性设为为true,即:
<setting name="aggressiveLazyLoading" value="false"/>
再一下执行过程:

此时的配置:启用延迟加载lazyLoadingEnabled=true和关闭按需加载aggressiveLazyLoading=true(即加载对象则加载所有属性)
Step1: 执行Mapper方法lazyLoadTest,实际只执行了select * from category where id=#{id}
Step2: 执行System.out.println(category.getName()),访问name属性,由于启用按需加载aggressiveLazyLoading=true,关闭按需加载,则加载category对象时加载该对象的所有属性,执行延迟加载sql脚本select * from products where categoryid=#{id},与数据库交互
Step3: 执行category.getProductList().size(),访问productList属性,该 性step2已加载好,此处无需数据库交互
对比上下两个step2可以发现 aggressiveLazyLoading=true /false的区别。

浙公网安备 33010602011771号