温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

java mybatis为何懒加载失效

发布时间:2026-09-02 18:19:18 来源:亿速云 阅读:96 作者:小樊 栏目:编程语言

Java + MyBatis 中,懒加载(延迟加载 / lazy loading)失效是一个比较常见的问题。下面从 原理 → 常见原因 → 排查与解决 给你系统说明。


一、MyBatis 懒加载的原理

MyBatis 的懒加载依赖:

  • resultMap 中的 association / collection
  • 配置:
    <setting name="lazyLoadingEnabled" value="true"/>
    <setting name="aggressiveLazyLoading" value="false"/>
    
  • 代理对象(CGLIB / Javassist)

只有在 真正调用关联属性 getter 方法 时,才会触发 SQL。


二、懒加载失效的常见原因(重点)

1️⃣ aggressiveLazyLoading=true(最常见)

<setting name="aggressiveLazyLoading" value="true"/>

⚠️ 如果为 true

只要访问对象的任意一个属性,就会加载所有懒加载属性

✅ 正确配置:

<setting name="lazyLoadingEnabled" value="true"/>
<setting name="aggressiveLazyLoading" value="false"/>

2️⃣ 调用了 toString() / equals() / hashCode()

例如:

System.out.println(user);

或:

user.toString();

⚠️ 这会触发 所有懒加载属性

✅ 解决:

  • 不要直接打印对象
  • 或重写 toString() 不调用关联属性

3️⃣ 使用了 resultType 而不是 resultMap

❌ 错误示例(不会懒加载):

<select id="getUser" resultType="User">

✅ 正确示例:

<resultMap id="userMap" type="User">
    <collection property="orders"
                select="selectOrdersByUserId"
                fetchType="lazy"/>
</resultMap>

懒加载必须基于 resultMap


4️⃣ fetchType="eager"

<collection property="orders" fetchType="eager"/>

❌ 强制立即加载

✅ 改为:

fetchType="lazy"

5️⃣ 在事务外访问懒加载属性

User user = userMapper.getUser(1);
// 事务已关闭
user.getOrders(); // 报错或失效

⚠️ MyBatis 懒加载依赖 SqlSession

✅ 解决:

  • @Transactional 内访问
  • 或使用 OpenSessionInView

6️⃣ 对象被序列化(JSON 返回)

return user; // Spring MVC → JSON

⚠️ JSON 序列化会调用 getter → 懒加载触发

✅ 解决:

  • 使用 DTO
  • @JsonIgnore

7️⃣ 一级缓存导致“看起来没懒加载”

MyBatis 一级缓存可能让你以为:

“怎么一查就有?”

实际是之前已经加载过


三、最小正确配置示例

<settings>
    <setting name="lazyLoadingEnabled" value="true"/>
    <setting name="aggressiveLazyLoading" value="false"/>
</settings>
<resultMap id="userMap" type="User">
    <id property="id" column="id"/>
    <collection property="orders"
                ofType="Order"
                select="selectOrders"
                fetchType="lazy"/>
</resultMap>

四、快速自查清单 ✅

  • [ ] 是否使用了 resultMap
  • [ ] lazyLoadingEnabled=true
  • [ ] aggressiveLazyLoading=false
  • [ ] 是否调用了 toString
  • [ ] 是否在事务内访问
  • [ ] 是否 JSON 序列化

如果你愿意,可以把 你的 Mapper / 配置 / 实体类 贴出来,我可以帮你精准定位是哪一条导致的失效。

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI