在 Java + MyBatis 中,懒加载(延迟加载 / lazy loading)失效是一个比较常见的问题。下面从 原理 → 常见原因 → 排查与解决 给你系统说明。
MyBatis 的懒加载依赖:
resultMap 中的 association / collection<setting name="lazyLoadingEnabled" value="true"/>
<setting name="aggressiveLazyLoading" value="false"/>
只有在 真正调用关联属性 getter 方法 时,才会触发 SQL。
aggressiveLazyLoading=true(最常见)<setting name="aggressiveLazyLoading" value="true"/>
⚠️ 如果为 true:
只要访问对象的任意一个属性,就会加载所有懒加载属性
✅ 正确配置:
<setting name="lazyLoadingEnabled" value="true"/>
<setting name="aggressiveLazyLoading" value="false"/>
toString() / equals() / hashCode()例如:
System.out.println(user);
或:
user.toString();
⚠️ 这会触发 所有懒加载属性
✅ 解决:
toString() 不调用关联属性resultType 而不是 resultMap❌ 错误示例(不会懒加载):
<select id="getUser" resultType="User">
✅ 正确示例:
<resultMap id="userMap" type="User">
<collection property="orders"
select="selectOrdersByUserId"
fetchType="lazy"/>
</resultMap>
懒加载必须基于
resultMap
fetchType="eager"<collection property="orders" fetchType="eager"/>
❌ 强制立即加载
✅ 改为:
fetchType="lazy"
User user = userMapper.getUser(1);
// 事务已关闭
user.getOrders(); // 报错或失效
⚠️ MyBatis 懒加载依赖 SqlSession
✅ 解决:
@Transactional 内访问OpenSessionInViewreturn user; // Spring MVC → JSON
⚠️ JSON 序列化会调用 getter → 懒加载触发
✅ 解决:
@JsonIgnoreMyBatis 一级缓存可能让你以为:
“怎么一查就有?”
实际是之前已经加载过
<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>
resultMaplazyLoadingEnabled=trueaggressiveLazyLoading=falsetoString如果你愿意,可以把 你的 Mapper / 配置 / 实体类 贴出来,我可以帮你精准定位是哪一条导致的失效。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。