9. Mybatis执行流程
9.1 问题目标:
- 理解各个组建的关系
- Sql的执行过程(参数映射、sql解析、执行和结果处理)
9.2 流程解析:

9.2.1 mybatis-config.xml示例

9.2.2 mappedStatement内容 解析
mappedStatement主要是将java入参转换成sql能够识别的类型,同时将sql的结果转成java能够识别的类型

9.3 问题回答:
- 读取MyBatis配置文件:mybatis-config.xml加载运行环境和映射文件
- 构造会话工厂SqlSessionFactory
- 会话工厂创建SqlSession对象 (包含了执行SQL语句的所有方法)
- 操作数据库的接口,Executor执行器,同时负责查询缓存的维护
- Executor接口的执行方法中有一个MappedStatement类型的参数,封装了映射信息
- 输入参数映射(将java类型转为sql类型)
- 输出结果映射(将sql类型转为java类型)
10. mybatis是否支持延迟加载:
10.1 什么是延迟加载:

10.2 测试示例:
代码:(其中也包括了mybatis执行流程)
public void testSelectById() throws IOException {
//1。加载mybatis的核心配置文件,获取 SqLSessionFactory
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder(),build(inputStream);
//2。获取SqLSession对象,用它来执行sgl
SqlSession sqlSession = sqlSessionFactory.openSession();
//3。执行sgl
//3.1 获取UserMapper接口的代理对象
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
User user = userMapper.selectById(6);
System.out.printin(user.getUsername());
System.out.println("----------------");
List<Order> orderList = user.getOrderListO:System.out.printin(orderList);
//4.关闭资源
sqlSession.close();
}
sql:


结果:可以看到直接查出了order信息

10.2.1 实现懒加载(延迟加载)
修改mapper文件:

结果:可以看到只有当我们需要获取订单信息的时候,才会去执行订单的查询

10.3 开启全局懒加载:
在mybatis-config.xml中配置:

10.4 延迟加载的原理:
通过代理对象实时去查询数据。

10.5 问题回答:

11. mybatis的一级、二级缓存用过吗?
11.1 概念介绍:
其中一二级缓存都是基于本地缓存的。

11.2 一级缓存:
基于PerpetualCache的HashMap本地缓存,其存储作用域为Session,当Session进行flush或close之后,该Session中所有Cache就将清空,默认开启一级缓存。
11.2.1 测试:
查询两次id=6的数据:

结果:可以看到在一个sqlsession中,查询只执行了一次

11.3 二级缓存:
二级缓存是基于namespace和mapper的作用域起作用的,不是依赖于sqlsession,默认也是采用PerpetualCache,hashmap存储
11.3.1 一级缓存作用域仅一个sqlsession示例:
创建2个sqlsession:

结果:可以看到执行了2次sql:
11.3.2 开启二级缓存:
- 第一步:开启

- 第二步:配置标签:

11.3.3 结果测试:
再次执上述代码,可以看到只执行了一次sql

11.3.4 二级缓存注意事项:
- 对于缓存数据更新机制,当某一个作用域(一级缓存 Session/二级缓存Namepaces)的进行了新增、修改、删除操作后,默认该作用域下所有select中的缓存将被clear
- 二级缓存需要缓存的数据实现Serializable接口
- 只有会话提交或者关闭以后,一级缓存中的数据才会转移到二级缓存中
11.4 问题回答:

11.5 为什么线上环境不建议开启一二级缓存?
MyBatis 的一级、二级缓存只作为 ORM 框架使用就行了,线上环境得关闭 MyBatis 的缓存机制。通过全文分析,不知道你有没有觉得 MyBatis 的缓存机制很鸡肋?
一级缓存来说对于有多个 SqlSession 或者分布式的环境下,数据库写操作会引起脏数据以及对于增删改多的操作来说,清除一级缓存会很频繁,这会导致一级缓存形同虚设。
二级缓存来说实现了 SqlSession 之间缓存数据的共享,除了跟一级缓存一样对于增删改多的操作来说,清除二级缓存会很频繁,这会导致二级缓存形同虚设;MyBatis 的二级缓存不适应用于映射文件中存在多表查询的情况,由于 MyBatis 的二级缓存是基于 namespace 的,多表查询语句所在的 namspace 无法感应到其他 namespace 中的语句对多表查询中涉及的表进行的修改,引发脏数据问题。虽然可以通过 Cache ref 来解决多表的问题,但这样做的后果是,缓存的粒度变粗了,多个 Mapper namespace 下的所有操作都会对缓存使用造成影响。
综上,生产环境要关闭 MyBatis 的缓存机制。你可能会问,你说生产环境不推荐用,那为啥很多面试官很喜欢问 MyBatis 的一级、二级缓存机制呢?那你把老周这篇丢给他就好了,最后你再反问面试官,你们生产环境有用 MyBatis 的一级、二级缓存机制吗?大多数的答案要么是没用或者它自己也不知道用没用就随便那几道题来面你。如果面试官回答生产环境用了的话,那你就把这些用的弊端跟面试官交流交流。
最后
以上就是负责河马最近收集整理的关于Mybatis相关知识点整理一级缓存二级缓存:的全部内容,更多相关Mybatis相关知识点整理一级缓存二级缓存内容请搜索靠谱客的其他文章。
发表评论 取消回复