mybatis的延迟加载机制
2022/1/17 23:41:24
本文主要是介绍mybatis的延迟加载机制,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
mybatis的延迟加载机制
延迟加载的含义: 用到的时候才会去进行相关操作
Mybatis支持association关联对象和collection关联集合对象的延迟加载
区别:association使用场景是一对一的关联查询,collection是一对多的关联查询
它的原理是
- 使用CGLIB动态代理创建目标对象的代理对象,当调用目标方法时,进入拦截器方法查看是否有值
- 比如调用
user.getAccount()
,拦截器invoke()
方法发现user.getAccount()
是null值,那么就会单独发送查询关联user对象的sql,把这个account
查询上来 - 然后调用
user.setAccount(account)
,于是user的account属性就有值了
示例
一个account,一个user表
CREATE TABLE `account` ( `acc_id` int(11) NOT NULL, `num` int(10) unsigned zerofill DEFAULT NULL, `user_id` int(11) NOT NULL, PRIMARY KEY (`acc_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; CREATE TABLE `user` ( `user_id` int(11) NOT NULL, `name` varchar(255) NOT NULL, PRIMARY KEY (`user_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
这里给user实体类增加了一个Account成员变量,用于测试延迟加载
public class User{ private Integer userId; private String name; private Account account; } public class Account{ private Integer accId; private Integer num; private Integer userId; }
当我们正常按id查询user时,只查询了一条sql语句
//java代码 User user = userMapper.selectByPrimaryKey(1); System.out.println("user.getUserId() = " + user.getUserId()); System.out.println("user.getName() = " + user.getName()); System.out.println("user.getAccount() = " + user.getAccount()); //sql select user_id, `name` from test.`user` where user_id = ? //结果 user.getUserId() = 1 user.getName() = test user.getAccount() = null
如果我们开启延迟加载
在Mybatis配置文件中,可以配置是否启用延迟加载
# 开启延迟加载 mybatis.configuration.lazy-loading-enabled=true # 将积极加载改为消极加载,即延迟加载 mybatis.configuration.aggressive-lazy-loading=false
在UserMapper.xml文件中的resultMap里加入一个association标签
(如果是一对一的关系用association标签,一对多用collection标签)
表示我不仅要把数据库中原有的user_id和name查出来
我还要将下列特征对应的属性一同延迟加载出来
-
property属性名称为
account
-
javaType全类名为
com.ifyyf.boot_test.pojo.Account
-
select查询方法位置是
com.ifyyf.boot_test.dao.AccountMapper.selectByUserId
(AccountMapper中的方法) -
column传入的参数是
user_id
(因为AccountMapper中的selectByUserId
是根据user_id查询的)
<resultMap id="BaseResultMap" type="com.ifyyf.boot_test.pojo.User"> <!--@mbg.generated--> <!--@Table test.`user`--> <id column="user_id" jdbcType="INTEGER" property="userId" /> <result column="name" jdbcType="VARCHAR" property="name" /> <association property="account" javaType="com.ifyyf.boot_test.pojo.Account" select="com.ifyyf.boot_test.dao.AccountMapper.selectByUserId" column="user_id"> </association> </resultMap>
结果分析
我们查看图片可以看到这里一共执行两次sql代码,而且执行的时机是不同的
select user_id,namefrom test.userwhere user_id = ?
,先通过id查询出来user对象,并输出了userId与name(这个是正常执行的)- 然后当其执行
System.out.println("user.getAccount() = " + user.getAccount());
时发现user.getAccount()
为null,然后又去执行了一次select * from account where user_id = ?
- 然后将查询出来的account结果set进了user,即
user.setAccount(account)
- 最后再打印出来
user.getAccount()
这篇关于mybatis的延迟加载机制的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-23Springboot应用的多环境打包入门
- 2024-11-23Springboot应用的生产发布入门教程
- 2024-11-23Python编程入门指南
- 2024-11-23Java创业入门:从零开始的编程之旅
- 2024-11-23Java创业入门:新手必读的Java编程与创业指南
- 2024-11-23Java对接阿里云智能语音服务入门详解
- 2024-11-23Java对接阿里云智能语音服务入门教程
- 2024-11-23JAVA对接阿里云智能语音服务入门教程
- 2024-11-23Java副业入门:初学者的简单教程
- 2024-11-23JAVA副业入门:初学者的实战指南