主题切换
延迟加载使用及原理
一、核心概念
1. 什么是延迟加载?
延迟加载(懒加载)是指在需要用到数据时才进行加载,不需要用到数据时不加载数据。 MyBatis支持一对一关联对象和一对多关联集合对象的延迟加载,默认关闭,需手动开启。
2. 配置开启延迟加载
在mybatis-config.xml中配置:
xml
<settings>
<!-- 开启延迟加载 -->
<setting name="lazyLoadingEnabled" value="true"/>
<!-- 按需加载(可选配置) -->
<setting name="aggressiveLazyLoading" value="false"/>
</settings>二、使用场景示例
以用户表和订单表的一对多关联为例:
java
public class User {
private Integer id;
private String username;
// 关联订单集合,延迟加载
private List<Order> orderList;
}
public class Order {
private Integer id;
private String name;
private Integer userId;
private User user;
}- 未开启延迟加载:查询用户时,会同时执行用户表和订单表的SQL查询;
- 开启延迟加载:查询用户时,仅执行用户表查询,
orderList为代理对象;当调用user.getOrderList()时,才会执行订单表的SQL查询。
三、底层实现原理
延迟加载通过CGLIB动态代理实现,流程如下:
- 创建代理对象:MyBatis为目标对象(如
User)创建CGLIB代理对象; - 拦截目标方法:当调用关联属性的getter方法(如
getOrderList())时,进入代理对象的拦截器invoke方法; - 判断并执行查询:拦截器发现目标属性(
orderList)为null,执行关联SQL查询; - 设置属性并返回:将查询结果设置到目标对象的属性中,再返回属性值。
面试相关问题
问:MyBatis是否支持延迟加载?默认开启吗?答: MyBatis支持一对一和一对多关联的延迟加载,默认不开启,需要在配置文件中通过
lazyLoadingEnabled=true手动开启。问:延迟加载的底层实现原理是什么?答: 延迟加载通过CGLIB动态代理实现:为目标对象创建代理对象,当调用关联属性的getter方法时,代理拦截器判断属性是否为null,若为null则执行关联SQL查询,将结果设置到属性中后再返回。
问:延迟加载的优缺点是什么?答: 优点是按需加载数据,减少不必要的SQL查询,提升性能;缺点是会增加一次额外的SQL查询,若所有关联属性都需要访问,总查询次数会增加,需结合业务场景使用。
问:如何配置MyBatis的延迟加载?答: 在
mybatis-config.xml的<settings>中配置lazyLoadingEnabled=true开启延迟加载,同时可配置aggressiveLazyLoading=false实现按需加载,避免不必要的触发。