大家好,我是锋哥。今天分享关于【MyBatis如何处理懒加载和预加载?】面试题。希望对大家有帮助;
MyBatis如何处理懒加载和预加载?
在 MyBatis 中,懒加载(Lazy Loading)和预加载(Eager Loading)是处理关联对象(如一对一、一对多映射)时的重要机制,用于平衡系统性能与数据完整性。以下是详细解释:
一、懒加载(Lazy Loading)
概念:
懒加载指在第一次访问关联对象时才执行 SQL 查询获取数据,而不是在主对象加载时立即加载关联数据。
例如:当查询一个用户 User 时,其关联的订单 Order 不会立即被加载,只有当你调用 user.getOrders() 时,MyBatis 才会发出 SQL 查询订单表。
实现机制:
MyBatis 使用 动态代理(CGLIB 或 JDK Proxy) 实现懒加载。
- 当调用主对象的 getter 方法时,会判断属性是否已加载;
- 若未加载,则通过代理执行延迟查询;
- 一旦加载完成,该属性的代理将被真实对象替代。
配置方式:
示例:
当 fetchType="lazy" 时,只有访问 user.getOrders() 时才执行查询。
优点:
- 减少初始查询开销;
- 提高系统响应速度;
- 适合大数据量或层级较深的对象关系。
缺点:
- 若频繁访问关联属性,可能导致 N+1 查询问题;
- 在关闭
SqlSession后访问懒加载属性会抛异常(因为连接已关闭)。
二、预加载(Eager Loading)
概念:
预加载即在查询主对象时立即加载其关联对象的数据,不需要等到访问时再查询。
适用于需要完整数据展示或频繁访问关联对象的场景。
实现方式: MyBatis 在定义映射关系时设置 fetchType="eager" 或在全局禁用懒加载:
或在具体映射中指定:
此时 MyBatis 在执行主查询时会立即加载 orders。
优点:
- 避免懒加载的延迟查询和会话关闭问题;
- 查询逻辑更简单。
缺点:
- 一次性加载大量数据可能影响性能;
- 对数据量较大、关联复杂的对象不适合。
三、总结对比
| 特性 | 懒加载(Lazy) | 预加载(Eager) |
|---|---|---|
| 查询时机 | 访问属性时 | 查询主对象时 |
| SQL执行次数 | 可能多次 | 一次性执行 |
| 性能 | 初始性能好,后期可能多次查询 | 一次加载,内存占用高 |
| 适用场景 | 数据量大、不常访问关联对象 | 需要完整数据或频繁访问关联对象 |
实际建议:
- 在数据层较深、访问不确定的情况下使用懒加载;
- 在展示页面或统计报表中需要完整信息时使用预加载;
- 结合 缓存机制(一级、二级缓存) 优化懒加载性能。
是否希望我结合一个具体的 User-Order 实体 XML 配置示例(包含一对多和懒加载触发)来演示实际写法?

浙公网安备 33010602011771号