Mybatis延迟加载的实现示例

 更新时间:2026年04月02日 10:03:23   作者:小王不爱笑132  
延迟加载是 MyBatis 的一种优化机制,也称为懒加载,本文就来详细的介绍一下Mybatis延迟加载的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

什么是延迟加载

延迟加载(Lazy Loading)是 MyBatis 的一种优化机制,也称为懒加载。它指的是在进行关联查询时,按需加载数据,而不是一次性加载所有关联数据,从而提高系统性能,减少不必要的数据库查询。

延迟加载配置

全局配置(SqlMapConfig.xml)

需要在 MyBatis 核心配置文件中开启延迟加载开关:

<settings>
    <!-- 开启延迟加载 -->
    <setting name="lazyLoadingEnabled" value="true"/>
    <!-- 将积极加载改为消极加载(按需加载) -->
    <setting name="aggressiveLazyLoading" value="false"/>
</settings>
  • lazyLoadingEnabled:全局开启延迟加载开关(默认 false)
  • aggressiveLazyLoading:是否开启积极加载(默认 false)
    • 积极加载:加载一个对象时,会同时加载所有关联对象
    • 消极加载:只有真正使用关联对象时才会加载

延迟加载实现(以 Account 和 User 为例)

1. 实体类定义

Account 类(包含 User 关联对象):

public class Account implements Serializable {
    private Integer id;
    private Integer uid;
    private Double money;
    // 关联的用户对象
    private User user;
    // getter/setter/toString省略
}

User 类:

public class User implements Serializable {
    private Integer id;
    private String name;
    private Date birthday;
    private String sex;
    private String address;
    // getter/setter/toString省略
}

2. Mapper 接口定义

AccountMapper 接口:

public interface AccountMapper {
    // 查询所有账户
    List<Account> findAll();
}

UserMapper 接口:

public interface UserMapper {
    // 根据ID查询用户
    User findById(Integer id);
}

3. Mapper 映射文件配置(关键)

AccountMapper.xml 中配置延迟加载:

<mapper namespace="com.qcby.mapper.AccountMapper">
    <!-- 延迟加载配置 -->
    <select id="findAll" resultMap="accountMap">
        select * from account
    </select>
    <resultMap id="accountMap" type="Account">
        <id column="id" property="id"/>
        <result column="uid" property="uid"/>
        <result column="money" property="money"/>
        <!-- 配置延迟加载 -->
        <association 
            property="user"        <!-- 关联对象在Account中的属性名 -->
            javaType="User"        <!-- 关联对象的类型 -->
            select="com.qcby.mapper.UserMapper.findById"  <!-- 延迟加载时执行的查询 -->
            column="uid"/>         <!-- 传递给select查询的参数(账户表中的uid字段) -->
    </resultMap>
</mapper>

UserMapper.xml 中需要有对应的查询方法:

<mapper namespace="com.qcby.mapper.UserMapper">
    <select id="findById" parameterType="int" resultType="User">
        select * from user where id = #{id}
    </select>
</mapper>

延迟加载测试代码

public class Test02 {
    private InputStream in;
    private SqlSession session;
    private AccountMapper mapper;
    @Before
    public void init() throws Exception {
        // 加载配置文件
        in = Resources.getResourceAsStream("SqlMapConfig.xml");
        // 创建工厂对象
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
        // 创建session对象
        session = factory.openSession();
        // 获取代理对象
        mapper = session.getMapper(AccountMapper.class);
    }
    @After
    public void destroy() throws Exception {
        session.close();
        in.close();
    }
    @Test
    public void testLazyLoading() {
        // 1. 查询所有账户(此时只会执行account表的查询)
        List<Account> accounts = mapper.findAll();
        // 2. 遍历账户列表
        for (Account account : accounts) {
            System.out.println("账户信息:" + account.getMoney());
            // 3. 当需要使用user属性时,才会执行user表的查询(延迟加载触发点)
            System.out.println("用户信息:" + account.getUser().getName());
        }
    }
}

延迟加载执行流程解析

  1. 执行mapper.findAll()时,MyBatis 只查询 account 表,获取账户基本信息
  2. 此时 account 对象中的 user 属性为代理对象(尚未查询数据库)
  3. 当执行account.getUser().getName()时,才会触发 User 查询
  4. 执行com.qcby.mapper.UserMapper.findById方法,传入 uid 参数
  5. 获取用户信息并赋值给 account 的 user 属性

延迟加载的优点

  1. 减少不必要的 SQL 查询,提高数据库性能
  2. 减少内存占用,只加载当前需要的数据
  3. 适用于关联数据较多但不一定都会使用的场景

注意事项

  1. 延迟加载只对关联查询有效(一对一、一对多等)
  2. 必须在核心配置文件中开启延迟加载开关
  3. 如果提前关闭 SqlSession,会导致延迟加载失败(无法执行后续查询)
  4. 延迟加载通过 CGLIB 或 JDK 动态代理实现,关联对象是代理对象

到此这篇关于Mybatis延迟加载的实现示例的文章就介绍到这了,更多相关Mybatis延迟加载内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • java实现简易超市管理系统 附源码下载

    java实现简易超市管理系统 附源码下载

    这篇文章主要介绍了java实现简易超市管理系统(含源码),本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-03-03
  • java中计算集合的交差并集示例代码

    java中计算集合的交差并集示例代码

    今天突然想Java如何计算集合的交差并集,主要是看Python语言的时候想起来的。下面这篇文章主要给大家介绍了关于java中计算集合的交差并集的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考借鉴,下面来一起看看吧。
    2017-08-08
  • Java中的同步与异步详细介绍

    Java中的同步与异步详细介绍

    这篇文章主要介绍了Java中的同步与异步详细介绍,具有一定参考价值,需要的朋友可以了解下。
    2017-11-11
  • JPA merge联合唯一索引无效问题解决方案

    JPA merge联合唯一索引无效问题解决方案

    这篇文章主要介绍了JPA merge联合唯一索引无效问题解决方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-09-09
  • IDEA编译时报常量字符串过长的解决办法

    IDEA编译时报常量字符串过长的解决办法

    本文主要介绍了IDEA编译时报常量字符串过长的解决办法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-07-07
  • 浅谈SpringCloud实现简单的微服务架构

    浅谈SpringCloud实现简单的微服务架构

    Spring Cloud是一系列框架的有序集合,本文就使用SpringCloud实现一套简单的微服务架构,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-01-01
  • mybatis-plus指定字段模糊查询的实现方法

    mybatis-plus指定字段模糊查询的实现方法

    最近项目中使用springboot+mybatis-plus来实现,所以下面这篇文章主要给大家介绍了关于mybatis-plus实现指定字段模糊查询的相关资料,需要的朋友可以参考下
    2022-04-04
  • 解决feign调用接口不稳定的问题

    解决feign调用接口不稳定的问题

    这篇文章主要介绍了解决feign调用接口不稳定的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-09-09
  • Java使用Canal同步MySQL数据到Redis

    Java使用Canal同步MySQL数据到Redis

    在现代微服务架构中,数据同步是一个常见的需求,特别是将 MySQL 数据实时同步到 Redis,下面我们就来看看Java如何使用Canal同步MySQL数据到Redis吧
    2024-11-11
  • Java中的AES加密算法用法示例详解

    Java中的AES加密算法用法示例详解

    这篇文章主要介绍了Java中的AES加密算法用法的相关资料,AES是一种广泛使用的对称加密算法,支持128位、192位和256位密钥,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2025-01-01

最新评论