您的位置:首页 > 房产 > 建筑 > 【Java面试】八、MyBatis篇

【Java面试】八、MyBatis篇

2025/1/27 12:39:14 来源:https://blog.csdn.net/llg___/article/details/139357821  浏览:    关键词:【Java面试】八、MyBatis篇

文章目录

  • 1、MyBatis执行流程
  • 2、MyBatis延迟加载使用
  • 3、MyBatis延迟加载的原理
  • 4、MyBatis的一级、二级缓存
    • 4.1 一级缓存
    • 4.2 二级缓存
    • 4.3 注意点
  • 5、面试

1、MyBatis执行流程

  • 从mybatis-config.xml读取配置(数据库连接信息,xml映射文件)

在这里插入图片描述

  • 构建会话工厂SqlSessionFactory,会话工厂,全局一个
  • SqlSessionFactory负责生产SqlSession,SqlSession包含执行SQL语句的所有方法

在这里插入图片描述

  • Executor执行器去操作数据库,其API方法有一个MappedStatement类型的参数,该类型的对象封装了SQL映射信息

在这里插入图片描述

  • Debug下MappedStatement对象,其属性值中,有SQL、Mapper层方法名称、结果集等信息,当时AOP采集数据库执行信息,SQL便来源于此对象
    在这里插入图片描述

流程:

在这里插入图片描述

2、MyBatis延迟加载使用

用户表和订单表一对多的关系,一个用户有多个订单。实体类:

在这里插入图片描述

Mapper.xml这么写:

在这里插入图片描述

此时,调用selectById:

在这里插入图片描述
发现其执行了两句SQL:

在这里插入图片描述

MyBatis延迟加载,即查询用户时,暂时不要去查询订单数据。当调用了user.getOrderList时,再去执行查订单的SQL。反之,一次都查出来,是立即加载。开启延迟加载,可加fetchType="lazy",开启局部延迟加载:

在这里插入图片描述
此时,再执行:

在这里插入图片描述
执行user.getOrderList时,才会执行查订单的SQL,注释调user.getOrderList,查订单的SQL直接不会去执行。最后,开启全局延迟加载可以修改MyBatis配置:

在这里插入图片描述

3、MyBatis延迟加载的原理

  • 使用动态代理,创建目标对象User的代理对象
  • 调用user.getOrderList方法时,进入代理对象的intercept方法(或revoke方法)
  • intercept方法(或revoke方法),做判断,如果user.getOrderList是null值,就执行sql查询订单列表
  • 查询完成后,调用user.setOrderList,封装订单信息到User的Order属性
  • 正常调用真实对象中的方法的Method实例,即user.getOrderList

在这里插入图片描述
最后,MyBatis使用哪种动态代理,取决于被代理的对象是否实现了接口(因为JDK动态代理有使用局限):

在这里插入图片描述

4、MyBatis的一级、二级缓存

在这里插入图片描述
MyBatis的一级、二级缓存,都是基于PerpetualCache,本质是一个HashMap。但二者作用域不同:

  • 一级缓存:生效的范围是session级别
  • 二级缓存:生效范围和session无关,作用域是namespace和mapper
    在这里插入图片描述

4.1 一级缓存

  • session级别,当Session进行flush或者close,该session里的所有缓存数据就会被全部清空
  • 默认开启

在这里插入图片描述

4.2 二级缓存

  • 基于namespace和mapper作用域,和SQLSession无关
  • 默认关闭状态

如下,两个SqlSession对象操作数据库,会查询两次,因为二级缓存默认关闭:
在这里插入图片描述

打开二级缓存:

  • 修改全局配置文件
    在这里插入图片描述
  • 使用<cache/>标签让当前mapper生效二级缓存
    在这里插入图片描述

4.3 注意点

  • 当某一个作用域(一级缓存Session/二级缓存 Namespaces)进行了新增、修改、删除操作后,该作用域下所有select的缓存数据被清空
  • 二级缓存需要缓存的数据必须实现Seaializable接口
  • SqlSession会话提交或关闭后,一级缓存的数据才会转移到二级缓存(如下,没有sqlSession1.close(),即使开启二级缓存,这里也会执行两次SQL查询)
    在这里插入图片描述

5、面试

在这里插入图片描述

在这里插入图片描述

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com