Mybatis延迟加载机制

MyBatis 的延迟加载(也称为懒加载)是一种优化策略,它允许在真正需要数据时才去数据库中查询,而不是在一开始就把所有关联数据都加载出来。这种机制能显著提升应用的性能,尤其是在处理大量关联数据时。下面详细介绍 MyBatis 延迟加载的机制。

核心原理

MyBatis 的延迟加载主要基于 Java 的动态代理模式。当查询主对象时,对于关联对象,MyBatis 不会立即执行关联查询,而是创建一个代理对象来替代关联对象。只有当真正访问关联对象的属性或方法时,代理对象才会触发相应的 SQL 查询,从数据库中加载实际数据。

配置延迟加载

要启用 MyBatis 的延迟加载,需要在配置文件中进行相应的设置。

在 mybatis-config.xml 中配置

    
    
    
    

  • lazyLoadingEnabled:设置为 true 表示开启延迟加载功能。
  • aggressiveLazyLoading:设置为 false 表示按需加载属性,即只有在访问关联对象的特定属性时才会触发查询;若设置为 true,则访问主对象的任何属性都会加载所有关联对象。
在映射文件中配置关联关系

以 resultMap 为例,使用 fetchType 属性指定关联对象的加载方式。


    
    
    
    
        
        
    

  • fetchType="lazy":表示使用延迟加载方式加载关联的订单信息。

延迟加载的执行流程

  1. 查询主对象:当执行主对象的查询时,MyBatis 会正常执行相应的 SQL 语句,将主对象的数据加载到内存中。对于关联对象,MyBatis 不会立即执行关联查询,而是创建一个代理对象来替代关联对象。
  2. 访问关联对象:当代码中尝试访问关联对象的属性或方法时,代理对象会捕获这个访问操作。
  3. 触发查询:代理对象检测到关联对象的数据还未加载,就会执行预先配置好的关联查询 SQL 语句,从数据库中加载关联对象的数据。
  4. 返回结果:将加载的关联对象数据填充到代理对象中,然后返回给调用者。

示例代码

以下是一个简单的 Java 代码示例,演示如何使用 MyBatis 的延迟加载功能。

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.InputStream;

public class LazyLoadingExample {
    public static void main(String[] args) throws Exception {
        // 加载配置文件
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

        // 创建 SqlSession
        try (SqlSession session = sqlSessionFactory.openSession()) {
            // 获取 UserMapper 代理对象
            UserMapper userMapper = session.getMapper(UserMapper.class);
            // 查询用户信息
            User user = userMapper.selectUserById(1);
            // 此时订单信息还未加载
            System.out.println("用户信息:" + user.getName());
            // 访问订单信息,触发延迟加载
            System.out.println("订单数量:" + user.getOrders().size());
        }
    }
}

注意事项

  • 代理对象的使用:由于延迟加载使用了代理对象,在某些情况下(如序列化)可能会出现问题。需要确保在使用时正确处理代理对象。
  • N + 1 查询问题:延迟加载可能会导致 N + 1 查询问题,即查询主对象需要 1 次查询,而查询每个主对象关联的 N 个对象又需要 N 次查询。可以通过合理配置 fetchType 和使用  来优化。

你可能感兴趣的:(ORM,java,后端,mybatis)