栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

mybatis的延迟加载机制

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

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查询的)

  
    
    
    
    
    
    
  
结果分析

我们查看图片可以看到这里一共执行两次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()

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/709761.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号