全部学科
Python全栈
python
NodeJS全栈
nodejs
小程序首页
📅 2026-05-20 6 分钟 ✍️ juanwangdev

延迟加载配置

延迟加载(Lazy Loading)在需要关联数据时才发起查询,减少不必要的数据库访问,优化查询性能。

全局配置

mybatis-config.xml 中开启:

XML
<settings>
  <!-- 开启全局懒加载 -->
  <setting name="lazyLoadingEnabled" value="true"/>
  
  <!-- 关闭侵入式懒加载 -->
  <setting name="aggressiveLazyLoading" value="false"/>
  
  <!-- 指定触发加载的方法 -->
  <setting name="lazyLoadTriggerMethods" value="equals,clone,hashCode,toString"/>
</settings>
配置项默认值说明
lazyLoadingEnabledfalse是否开启全局懒加载
aggressiveLazyLoadingfalse (3.4.1+)侵入式加载:true 时调用任意方法触发全部加载
lazyLoadTriggerMethodsequals,clone,hashCode,toString触发加载的方法列表

局部控制:fetchType

在 association/collection 上单独配置覆盖全局设置:

XML
<resultMap id="orderResultMap" type="Order">
  <id property="id" column="id"/>
  <!-- 延迟加载用户信息 -->
  <association property="user"
               column="user_id"
               javaType="User"
               select="selectUser"
               fetchType="lazy"/>
  
  <!-- 立即加载订单项 -->
  <collection property="items"
              column="id"
              ofType="OrderItem"
              select="selectOrderItems"
              fetchType="eager"/>
</resultMap>
fetchType行为
lazy访问属性时才加载
eager查询主数据时同时加载
不配置继承全局 lazyLoadingEnabled 行为

fetchType 优先级高于全局配置,适合对特定关联做差异化加载策略。

lazyLoadTriggerMethods 详解

配置哪些方法调用会触发延迟加载:

XML
<!-- 仅调用 toString 时触发加载 -->
<setting name="lazyLoadTriggerMethods" value="toString"/>

<!-- 禁用所有方法触发(仅访问属性时加载) -->
<setting name="lazyLoadTriggerMethods" value=""/>

常见场景:

Java
Order order = mapper.selectOrder(1);

// aggressiveLazyLoading=false 时,以下不触发加载
order.getId();
order.getOrderNo();

// aggressiveLazyLoading=true 时,调用任意方法即触发
order.toString();  // 会触发 user 和 items 全部加载

// 仅访问属性时才加载(推荐模式)
User user = order.getUser();  // 此时触发 user 查询

aggressiveLazyLoading 行为差异

XML
<!-- aggressiveLazyLoading = true -->
<!-- 调用 order.toString() 会同时加载 user 和 items -->

<!-- aggressiveLazyLoading = false(推荐) -->
<!-- 仅访问 order.getUser() 时加载 user,访问 order.getItems() 时加载 items -->

3.4.1 版本后 aggressiveLazyLoading 默认值为 false,建议保持默认,避免不必要的数据加载。

延迟加载与序列化

延迟加载的代理对象在序列化时会触发加载:

Java
// Jackson/Fastjson 序列化时,会触发懒加载
String json = objectMapper.writeValueAsString(order);
// 结果:user 和 items 被加载并序列化

若需序列化但不触发加载:

Java
// 方案1:使用 DTO 手动转换
OrderDTO dto = new OrderDTO(order.getId(), order.getOrderNo());

// 方案2:配置 Jackson 忽略关联属性
@JsonIgnore
private User user;

完整配置示例

XML
<settings>
  <setting name="lazyLoadingEnabled" value="true"/>
  <setting name="aggressiveLazyLoading" value="false"/>
  <setting name="lazyLoadTriggerMethods" value="equals,clone,hashCode,toString"/>
</settings>

<resultMap id="blogResultMap" type="Blog">
  <id property="id" column="id"/>
  <result property="title" column="title"/>
  <association property="author"
               column="author_id"
               javaType="Author"
               select="selectAuthor"
               fetchType="lazy"/>
  <collection property="comments"
              column="id"
              ofType="Comment"
              select="selectComments"
              fetchType="lazy"/>
</resultMap>

要点总结

  • lazyLoadingEnabled=true 开启全局延迟加载。
  • aggressiveLazyLoading=false 避免侵入式加载,推荐保持默认。
  • fetchType 可局部覆盖全局配置,实现差异化加载策略。
  • lazyLoadTriggerMethods 控制哪些方法调用触发加载。
  • 序列化会自动触发延迟加载,需使用 DTO 或 @JsonIgnore 避免。
  • 合理配置延迟加载可显著减少不必要的数据库查询。

📝 发现内容有误?点击此处直接编辑

← 上一篇 嵌套查询与 N+1 问题
下一篇 → 一级缓存机制
想查看更多题目和详细解析?
小程序提供完整的题库、模拟考试和详细解析
马上就来

长按或扫描二维码,立即体验

扫码体验小程序
马上就来
使用微信扫描二维码
立即体验完整题库