八、(了解即可)MyBatis懒加载(或者叫延迟加载)

news/2024/10/31 3:26:15/

在这里插入图片描述

文章目录

  • 八、懒加载(了解即可)
    • 8.1 为啥需要懒加载?
    • 8.2 懒加载是什么?
    • 8.3 开启方式
    • 8.4 既然fetchType可以控制懒加载那么我仅仅配置fetchType不配置全局的可以吗?
    • 8.5 aggressiveLazyLoading是做什么么的?
    • 8.6 注意点
    • 8.7 案例验证懒加载
      • 准备工作
      • 场景1:验证全局懒加载
      • 场景2:验证局部懒加载
  • 本人其他相关文章链接

八、懒加载(了解即可)

所谓的懒加载,延迟加载是同一个东西。指的就是需要才会加载,不需要就不会加载。

8.1 为啥需要懒加载?

答案:懒加载针对级联使用的,懒加载的目的是减少内存的浪费和减轻系统负担。

8.2 懒加载是什么?

答案:可以理解为按需加载,当调用到关联的数据时才与数据库交互否则不交互。

再具体点来说
比如user表和role表有关联关系,有这样一条语句:查询uesr的同时将user的某一列数据作为参数一并查询role表符合条件的数据,mybatis里叫做级联。只要执行这条语句,就会将这两张表符合需求的信息一起加载出来。而懒加载只会加载uesr表的数据出来不加载role表的数据。

8.3 开启方式

  • 方式1:全局设置,在mybatis-config.xml中进行开启
<settings><!--开启延迟加载--><setting name="lazyLoadingEnabled" value="true"/></settings>
  • 方式2:局部设置,<association>和<collection>有个fetchType属性可以覆盖全局的懒加载状态:eager表示这个级联不使用懒加载要立即加载,lazy表示使用懒加载。

8.4 既然fetchType可以控制懒加载那么我仅仅配置fetchType不配置全局的可以吗?

答案:是可以的,

8.5 aggressiveLazyLoading是做什么么的?

它是控制具有懒加载特性的对象的属性的加载情况的。
true表示如果对具有懒加载特性的对象的任意调用会导致这个对象的完整加载,false表示每种属性按照需要加载。

8.6 注意点

  • 注意点1:只有分步查询才能让懒加载有效,也就是只能使用单条查询,而不能使用连表查询语句。
  • 注意点2:现实中用这个的场景我个人感觉也不太多,因为当多表查询,比如5个表查询的时候,写<resultMap>标签嵌套层次太多,太复杂不易理解,且不易使用。
  • 注意点3:懒加载分全局设置和局部设置。
  • 注意点4:如果是全局设置开启,要注意标签的放置位置,因为在mybatis-config.xml中标签是有顺序的。

8.7 案例验证懒加载

我有个用户表,有个地址表,其中地址表可以根据用户id进行关联查询,具体测试如下

准备工作

  • User
@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class User {//idprivate Integer id;//用户名称private String username;//用户密码private String password;//用户手机号码private String mobile;//性别private Integer gender;//最近一次登录IP地址private String lastLoginIp;private Address address;
  • Address
@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class Address implements Serializable {//idprivate Integer id;//用户名称private String name;//用户IDprivate Integer userId;private List<User> userList = new ArrayList<>();
}
  • mybatis-config.xml
<settings><!--开启延迟加载--><setting name="lazyLoadingEnabled" value="true"/>
</settings>
  • SelectMapper
List<User> getAllUser();
  • SelectMapper.xml
<resultMap id="userResultMapLazy" type="User"><id property="id" column="id"></id><result property="username" column="username"></result><result property="password" column="password"></result><result property="mobile" column="mobile"></result><result property="gender" column="gender"></result><result property="lastLoginIp" column="last_login_ip"></result><collection property="address" column="id" select="com.mybatis.mapper.AddressMapper.getAddressByUserId"></collection></resultMap><!--List<User> getAllUser();--><select id="getAllUser" resultType="User" resultMap="userResultMapLazy">select * from litemall_user</select>
  • AddressMapper
Address getAddressByUserId(@Param("userId") Integer userId);
  • AddressMapper.xml
<select id="getAddressByUserId" resultType="Address">select * from litemall_address where user_id = #{userId}
</select>

场景1:验证全局懒加载

当开启全局懒加载时,只调用item.getUsername()属性时,可以看到只调用user表sql,没有调用address表sql

@Testpublic void lazyLoading(){SqlSession sqlSession = SqlSessionUtils.getSqlSession();AddressMapper addressMapper = sqlSession.getMapper(AddressMapper.class);SelectMapper selectMapper = sqlSession.getMapper(SelectMapper.class);List<User> userList = selectMapper.getAllUser();userList.forEach(item -> {System.out.println(item.getUsername());
//            System.out.println(item.getAddress());});}

日志打印:

在这里插入图片描述

当调用item.getAddress()地址属性时

@Testpublic void lazyLoading(){SqlSession sqlSession = SqlSessionUtils.getSqlSession();AddressMapper addressMapper = sqlSession.getMapper(AddressMapper.class);SelectMapper selectMapper = sqlSession.getMapper(SelectMapper.class);List<User> userList = selectMapper.getAllUser();userList.forEach(item -> {System.out.println(item.getUsername());System.out.println(item.getAddress());});}

日志打印:

在这里插入图片描述

场景2:验证局部懒加载

其他不变,只设置<collection>属性为fetchType=“eager”,其中eager代表立即加载

<resultMap id="userResultMapLazy" type="User"><id property="id" column="id"></id><result property="username" column="username"></result><result property="password" column="password"></result><result property="mobile" column="mobile"></result><result property="gender" column="gender"></result><result property="lastLoginIp" column="last_login_ip"></result><collection property="address" column="id" select="com.mybatis.mapper.AddressMapper.getAddressByUserId" fetchType="eager"></collection></resultMap>
@Testpublic void lazyLoading(){SqlSession sqlSession = SqlSessionUtils.getSqlSession();AddressMapper addressMapper = sqlSession.getMapper(AddressMapper.class);SelectMapper selectMapper = sqlSession.getMapper(SelectMapper.class);List<User> userList = selectMapper.getAllUser();userList.forEach(item -> {System.out.println(item.getUsername());});}

日志打印:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hQtkZzkO-1683265362370)(C:\Users\NINGMEI\Desktop\Typora文档图片\MyBatis\image-20230505132948595.png)]

最终结论:局部设置生效了,因为调接口打印输出只调用了item.getUsername(),而没有调用item.getAddress(),所以如果局部设置不生效,那么不会调用查询地址的sql。

本人其他相关文章链接

1.一、MyBatis简介:MyBatis历史、MyBatis特性、和其它持久化层技术对比、Mybatis下载依赖包流程
2.二、搭建MyBatis采用xml方式,验证CRUD(增删改查操作)
3.三、MyBatis核心配置文件详解
4.四、MyBatis获取参数值的两种方式(重点)
5.五、MyBatis的增删改查模板(参数形式包括:String、对象、集合、数组、Map)
6.六、MyBatis特殊的SQL:模糊查询、动态设置表名、校验名称唯一性
7.七、MyBatis自定义映射resultMap
8.八、(了解即可)MyBatis懒加载(或者叫延迟加载)
9.九、MyBatis动态SQL
10.十、MyBatis的缓存
11.十一、MyBatis的逆向工程
12.十二、MyBatis分页插件


http://www.ppmy.cn/news/62049.html

相关文章

Python每日一练:小艺的口红(暴力、二分、图论三种方法)代写匿名信

文章目录 前言0、题目一、暴力查找二、二分查找三、有序二叉树总结&#xff08;代写匿名信&#xff09; 前言 很明显小艺的口红问题是考的是查找算法&#xff0c;对于这种一次性查找&#xff0c;直接暴力就行了&#xff0c;当然咱是为了学习&#xff0c;所以用来练练各种查找&…

java环境Springboot框架中配置使用GDAL,并演示使用GDAL读取shapefile文件

GDAL是应用广泛的空间数据处理库&#xff0c;可以处理几何、栅格数据&#xff0c;Springboot是常用的JAVA后端开发框架。本文讲解如何在Springboot中配置使用GDAL。本文示例中使用的GDAL版本为3.4.1&#xff08;64位&#xff09; 图1 GDAL读取shp效果 一、部署GDAL类库 将GDA…

数字信号处理4

昨天是星期天&#xff0c;休息了一天&#xff0c;今天继续学习&#xff1a; 1、连续幅度信号的量化&#xff1a; 一个数字信号是一个数字序列&#xff0c;也就是说这个数字信号就可以用有限个数字来表示。 量化&#xff1a;通过把每个样本值表示为一个有限的数字&#xff0c…

[pgrx开发postgresql数据库扩展]附.更新开发环境安装脚本

pgrx更新到0.83之后&#xff0c;我本来还没感觉&#xff0c;但是我五一放假一来&#xff0c;发现我的WSL环境居然就挂了…… 果然是非稳定版本就是不靠谱了…… 所以我干脆搞了个虚拟机&#xff0c;重新安装了一套&#xff0c;还别说&#xff0c;更新到了0.83之后&#xff0c;安…

Yolov1 源码讲解 loss.py

结构 1.lt rb我觉得不是很合适 正确来说是lb rt 因为比较出来的都是左下和右上坐标 比如前两个&#xff0c;都是max出来的 选两个box左下坐标中最大的&#xff0c; 后两个则是右上坐标中最小的 那也就形成了交集面积 但是代码中仍然是lt rb我也就直接这样说 而算出lt和r…

数字孪生遇上VR:未来的新生态

数字孪生和虚拟现实&#xff08;VR&#xff09;是当今技术领域备受关注的两个概念。 数字孪生作为物理世界的数字映像&#xff0c;已经在许多行业得到了广泛应用。而VR则是一种基于计算机生成的三维交互式虚拟环境&#xff0c;被广泛应用于娱乐、教育和游戏等领域。 数字孪生…

【高并发】网络模式

I/O 多路复用 多线程创建 服务器的主进程负责监听客户的连接&#xff0c;一旦与客户端连接完成&#xff0c;accept() 函数就会返回一个「已连接 Socket」&#xff0c;这时就通过 fork() 函数创建一个子进程&#xff0c;实际上就把父进程所有相关的东西都复制一份&#xff0c;…

Illustrator如何使用图层与蒙版之实例演示?

文章目录 0.引言1.绘制可爱冰淇淋图标2.霓虹渐变立体文字海报3.炫彩花纹背景 0.引言 因科研等多场景需要进行绘图处理&#xff0c;笔者对Illustrator进行了学习&#xff0c;本文通过《Illustrator CC2018基础与实战》及其配套素材结合网上相关资料进行学习笔记总结&#xff0c;…