MyBatis延迟加载策略详解
延迟加载就是在需要用到数据的时候才进行加载,不需要用到数据的时候就不加载数据。延迟加载也称为懒加载。
优点:在使用关联对象时,才从数据库中查询关联数据,大大降低数据库不必要开销。
缺点:因为只有当需要用到数据时,才会进行数据库查询,这样在大批量数据查询时,因为查询工作也需要耗费时间,所以可能造成用户等待时间变长,造成用户体验下降。
数据库模型准备
下面我们给出的就是一个数据库关系模型,在后面的例子中一这两个表为基础讲解MyBatis延迟加载。我们假定Article(文章)与Tag(标签)是一对多的关系。

注意面这段话的表述:表的关联关系大致可以分为四种:一对一、多对一、一对多、多对多,但是实质上从单独一个表的角度上来看只存在一对一和一对多关系;而一对一和一对多的关系都能通过下列两个表来表示,以Article表的角度上来看,一个Article数据可以由多个Tag数据行对应,这就是一对多的关系;而一个Tag数据只能与一个Article关联,这就是一对一的关系。所以了解了MyBatis一对多的延迟加载的配置(双向)也就学会了四种关联模式的配置。
第一步:配置MyBatis核心配置文件
如果想使用延迟加载策略,就需要在MyBatis全局配置文件中开启延迟加载策略:

参数详情参考官方文档:settings配置
我们在MyBatis全局配置文件(SqlMapConfig.xml)中添加下列代码:
<settings>
<setting name="lazyLoadingEnabled" value="true"/>
<setting name="aggressiveLazyLoading" value="true"/>
</settings>
第二步:配置映射文件
预先定义ArticleMapper和TagMapper接口
ArticleMapper接口:
public interface ArticleMapper {
Article getArticleById(Long id);
}
TagMapper接口:
public interface TagMapper {
Tag getTagById(Long id);
Tag getTagsByArticleId(Long id);
}
配置ArticleMapper.xml映射文件(一对多配置)
在不使用延迟加载的情况下,我们通常使用的是关联查询,直接查出关联对象的数据:
<mapper namespace="com.tjd.spring_mybatis_plus.mapper.ArticleMapper">
<resultMap id="articleMap" type="Article">
<id column="id" property="id"></id>
<result column="title" property="title"></result>
<result column="content" property="content"></result>
<collection property="tags" ofType="Tag">
<id column="tid" property="id"></id>
<result column="tcontent" property="content"></result>
</collection>
</resultMap>
<select id="getArticleById" resultMap="articleMap" parameterType="long">
SELECT
a.id id,
a.title title,
a.content content,
t.id tid,
t.content tcontent
FROM
article a
LEFT JOIN tag t ON a.id = t.article_id
WHERE
a.id = #{id}
</select>
</mapper>
如果要想使用延迟加载策略,那么映射文件配置就不能采用连接查询了,因为这样一旦SQL语句执行了,关联数据也就查询出来了,所以我们要将原来的关联查询,转换成单表查询:
<mapper namespace="com.tjd.spring_mybatis_plus.mapper.ArticleMapper">
<resultMap id="articleMap" type="Article">
<id column="id" property="id"></id>
<result column="title" property="title"></result>
<result column="content" property="content"></result>
<collection property="tags" ofType="Tag" column="id" select="com.tjd.spring_mybatis_plus.mapper.TagMapper.getTagsByArticleId" ></collection>
</resultMap>
<select id="getArticleById" resultMap="articleMap" parameterType="long">
select * from article where id=#{id}
</select>
</mapper>
collection标签属性:
- ofType:用于指定集合元素的数据类型。
- select:指定用于查询关联表数据SQL语句的ID。
- column:是用于指定使用哪个字段的值作为条件查询。
在TagMapper.xml映射文件中定义如下语句:
<!--在前面定义的ArticleMapper.xml映射文件中collection标签中select属性就是指向的这个SQL语句-->
<select id="getTagsByArticleId" parameterType="long" resultType="Article">
select * from tag where article_id=#{article_id}
</select>
做到这里,一对多的延迟加载配置就完成了,在执行ArticleMapper中ID为getArticleById的SQL语句时,并不会立即执行TagMapper中的getTagsByArticleId,而是在需要时再执行getTagsByArticleId,从而达到了延迟加载的目的。
配置TagMapper.xml映射文件(一对一 或 多对一 配置)
<mapper namespace="com.tjd.spring_mybatis_plus.mapper.TagMapper">
<resultMap id="tagMap" type="Tag">
<id column="id" property="id"></id>
<result column="content" property="content"></result>
<association property="article" column="article_id" javaType="Article" select="com.tjd.spring_mybatis_plus.mapper.ArticleMapper.getArticleById"></association>
</resultMap>
<!--并没有采用关联查询-->
<select id="getTagById" parameterType="long" resultMap="tagMap">
select * from tag where id=#{id}
</select>
<select id="getTagsByArticleId" parameterType="long" resultMap="Article">
select * from tag where article_id=#{article_id}
</select>
</mapper>
association标签属性:
- ofType:用于指定集合元素的数据类型。
- select:指定用于查询关联表数据SQL语句的ID。
第三步:测试
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class LazyLoadTest {
@Autowired
private ArticleMapper articleMapper;
@Autowired
private TagMapper tagMapper;
@Test
public void test(){
Tag tag = tagMapper.getTagById(1L);
Article article = tag.getArticle();
List<Tag> tags = article.getTags();
}
}
如果想要验证延迟加载策略,我们推荐采用Debug,开启MyBatis SQL日志功能,然后每执行一条语句就会发现控制台输出一条SQL语句,这就表明它的关联数据是延迟查询的。

博主的个人首页,有兴趣的小伙伴可以关注一下:www.bigcoder.cn(部分地区网速比较慢,各位看官稍等哈)
MyBatis延迟加载策略详解的更多相关文章
- MyBatis 延迟加载代码详解
在我们的实际开发中,会面临各种各样的查询操作.如果单表查询能满足业务需求.尽量用单表查询,因为单表查询的效率比多表关联查询快. 那么当业务需求需要用到的数据来源于多张表的时候,单表查询无法解决,Myb ...
- MyBatis Mapper XML 详解
MyBatis Mapper XML 详解 MyBatis 真正的力量是在映射语句中.这里是奇迹发生的地方.对于所有的力量,SQL 映射的 XML 文件是相当的简单.当然如果你将它们和对等功能的 JD ...
- MyBatis核心配置文件详解
------------------------siwuxie095 MyBatis 核心配置文件详解 1.核心 ...
- Mybatis源码详解系列(四)--你不知道的Mybatis用法和细节
简介 这是 Mybatis 系列博客的第四篇,我本来打算详细讲解 mybatis 的配置.映射器.动态 sql 等,但Mybatis官方中文文档对这部分内容的介绍已经足够详细了,有需要的可以直接参考. ...
- 七牛云存储Python SDK使用教程 - 上传策略详解
文 七牛云存储Python SDK使用教程 - 上传策略详解 七牛云存储 python-sdk 七牛云存储教程 jemygraw 2015年01月04日发布 推荐 1 推荐 收藏 2 收藏,2.7k ...
- mybatis代码生成器配置文件详解
mybatis代码生成器配置文件详解 更多详见 http://generator.sturgeon.mopaas.com/index.html http://generator.sturgeon.mo ...
- 深入浅出mybatis之启动详解
深入浅出mybatis之启动详解 MyBatis功能丰富,但使用起来非常简单明了,今天我们来追踪一下它的启动过程. 目录 如何启动MyBatis 如何使用MyBatis MyBatis启动过程 如何启 ...
- guava-retrying 源码解析(等待策略详解)
一.等待策略相关类: 1.等待策略接口:WaitStrategy接口 该接口只有一个方法,就是返回尝试失败之后,下一次尝试之前的等待时间.long computeSleepTime(Attempt f ...
- 《深入理解mybatis原理2》 Mybatis初始化机制详解
<深入理解mybatis原理> Mybatis初始化机制详解 对于任何框架而言,在使用前都要进行一系列的初始化,MyBatis也不例外.本章将通过以下几点详细介绍MyBatis的初始化过程 ...
- Mybatis案例超详解(上)
Mybatis案例超详解(上) 前言: 本来是想像之前一样继续跟新Mybatis,但由于种种原因,迟迟没有更新,快开学了,学了一个暑假,博客也更新了不少,我觉得我得缓缓,先整合一些案例练练,等我再成熟 ...
随机推荐
- Python设计模式----2.工厂模式
工厂方法模式是简单工厂模式的衍生,解决了许多简单工厂模式的问题 首先完全实现'开-闭 原则',实现了可扩展.其次更复杂的层次结构,可以应用于产品结果复杂的场合. 工厂方法模式的对简单工厂模式进行了抽象 ...
- MogDB/OpenGauss数据库中通过参数控制抓取慢sql
MogDB/OpenGauss 数据库中通过参数控制抓取慢 sql 本文出处:https://www.modb.pro/db/221556 mogdb 数据库中可以通过打开相应的参数抓取慢 sql,该 ...
- BTC的数据结构
区块链是一个个block所构成的链,或者链表状的数据结构,在比特币中或者区块链中,一个重要的组成部分是哈希指针 指针 在程序运行过程中,需要用到数据.最简单的是直接获取数据,但当数据本身较大,需要占用 ...
- js 使用flow
前言 what is flow?我想是的,很多人都没有接触过,的确,他是一个新的项目,是的facebook开发的东西,一般还是可以的,有必要去学习一下,在react还是比较重要的. 它做的一件事叫做静 ...
- 在windows电脑中安装redis
1,github下载地址:https://github.com/MSOpenTech/redis/tags 2,下载完成后,解压到对应文件夹 3,打开redis.windows.conf,在#requ ...
- Web前端 -- 利用Babel来将ES6转化为ES5代码
一.简介 Babel用来将ES6代码转为ES5代码. 二.安装 安装命令行转码工具 Babel提供babel-cli工具,用于命令行转码.它的安装命令如下: npm install --global ...
- 力扣571(MySQL)-给定数字的频率查询中位数(困难)
题目: Numbers 表保存数字的值及其频率. 在此表中,数字为 0, 0, 0, 0, 0, 0, 0, 1, 2, 2, 2, 3,所以中位数是 (0 + 0) / 2 = 0. 请编写一个查询 ...
- 从Redis7.0发布看Redis的过去与未来
简介: 经历接近一年的开发.三个候选版本,Redis 7.0终于正式发布,这是Redis历史上改变最多的一个大版本,它不仅包含了50多个新命令,还有大量核心新特性与改进,这些不仅能够解决用户使用中的诸 ...
- Arthas 初探--安装初步适用
简介: 由于在项目中遇到一种情况,某段代码在进行单元测试和在 tomcat 容器中运行的性能相差数百倍,因此需要分析在不同环境下某个方法执行的具体时间,从而确定问题.Arthas 可以做到无侵入的监控 ...
- T级内存,创建效率提升10倍以上,阿里云 KVM异构虚拟机启动时间优化实践
简介: 阿里云工程师李伟男和郭成在 KVM Forum 2020 上详细介绍了阿里云 KVM 虚拟机创建及启动时间优化的具体技术实现,本文根据其演讲整理而成. 对于云计算用户来说,过长的 KVM 虚拟 ...