10. MyBatis缓存

网友投稿 672 2022-11-21

10. MyBatis缓存

10. MyBatis缓存

10. MyBatis缓存

前言

上一篇章我们已经了解了 MyBatis 加载策略,本篇章再来认识一下 MyBatis 缓存。

什么是缓存?

# 缓存和缓冲的区别1. 缓冲: buffer 内存中的一块区域,提高单次IO读写效率 (一次读写1024byte,要比一次读写1byte快) (用空间换时间)2. 缓存: cache 内存或硬盘中的一块区域, 提高多次读效率(频繁操作) (用空间换时间) ( 酷狗听歌: 1. 第一次听歌, 这首歌在本地缓存中没有, 要从网络上-,会-到硬盘上,作为缓存(比较慢) 2. 再次听歌, 这首歌本地缓存有了, 不需要网络上-(比较快) )

为什么使用缓存?

“ 提高再次查询效率的 ”

什么样的数据适合做缓存?

“ 经常访问但又不经常修改的数据... ”

缓存是用来提高再次查询效率的,所有的持久层框架基本上都有缓存机制 Mybatis也提供了缓存策略,分为一级缓存,二级缓存

image-20210328235239433

一级缓存

介绍

MyBatis 一级缓存是:SqlSession级别的缓存,默认开启,不需要手动配置。

image-20210329000207622

下面我们来写一个案例来验证一下效果。

验证

需求:根据id查询用户

1.使用同一个 SqlSession 对象,执行两次查询,查看是否会执行两次 SQL

image-20210329001315975

@Testpublic void test04(){ //1. 同一个sqlsession (同一用户) SqlSession session = MyBatisUtil.getSqlSession(); //2. 第一次查询 : 要查询数据库,往缓存中放一份 OrdersMapper mapper = session.getMapper(OrdersMapper.class); // 查询用户id=41的用户以及拥有的订单 User user = mapper.findUserByIdWithOrders(41); System.out.println(user); //3. 第二次查询: 不需要, 因为一级缓存已经有了 OrdersMapper mapper2 = session.getMapper(OrdersMapper.class); // 查询用户id=41的用户以及拥有的订单 User user2 = mapper.findUserByIdWithOrders(41); System.out.println(user); MyBatisUtil.commitAndClose(session);}

2.一级缓存需要如何才可以失效呢?

缓存失效:1. 手动清除缓存 clearCache()2. 执行SqlSession的C(增加)U(更新)D(删除)操作,会自动清除缓存3. 事务结束: commit()、rollback(), close()方法, 自动清除缓存

下面我们使用 手动清除缓存 clearCache() 来演示一下缓存失效的情况,如下:

image-20210329001626498

3.完整示例代码

/** * 一级缓存: 默认开启 * * 缓存失效: * 1. 手动清除缓存 clearCache() * 2. 执行SqlSession的C(增加)U(更新)D(删除)操作,会自动清除缓存 * 3. 事务结束: commit()、rollback(), close()方法, 自动清除缓存 */@Testpublic void test04(){ //1. 同一个sqlsession (同一用户) SqlSession session = MyBatisUtil.getSqlSession(); //2. 第一次查询 : 要查询数据库,往缓存中放一份 OrdersMapper mapper = session.getMapper(OrdersMapper.class); // 查询用户id=41的用户以及拥有的订单 User user = mapper.findUserByIdWithOrders(41); System.out.println(user); session.clearCache(); // 手动清除缓存 //3. 第二次查询: 不需要, 因为一级缓存已经有了 OrdersMapper mapper2 = session.getMapper(OrdersMapper.class); // 查询用户id=41的用户以及拥有的订单 User user2 = mapper.findUserByIdWithOrders(41); System.out.println(user); MyBatisUtil.commitAndClose(session);}

分析

一级缓存是SqlSession范围的缓存,不同的SqlSession之间的缓存区域是互相不影响的,执行SqlSession的C(增加)U(更新)D(删除)操作,或者调用clearCache()、commit()、close()方法,都会清空缓存。

image-20210329143943612

二级缓存

介绍

MyBatis的二级缓存虽然是默认开启的,但需要在映射文件中配置​​​​标签才能使用,而且要求实体类的必须实现序列化接口

image-20210329151204913

根据上图,前面一级缓存是指默认一次会话中的查询缓存,而二级缓存则是针对一个映射查询的多次会话的查询缓存。

下面我们来配置一下,配置一个订单表查询的二级缓存。

验证

1. mybatis全局配置,默认值就是开启了二级缓存

在 ​​sqlMapConfig.xml​​ 设置如下:

image-20210329173401461

2. 指定需要开启二级缓存的映射配置文件

设置订单映射配置文件 ​​OrdersMapper.xml​​ 的二级缓存,如下:

image-20210329173735945

3.实体类要实现序列化接口

image-20210406000445987

4.编写测试方法:使用两个查询sqlsession进行查询,确认二级缓存的效果

/** * 二级缓存: * 1. 作用范围: 比一级大, 跨sqlsession * 2. 存储介质: 内存/硬盘 *

* 注意: * 1. 核心配置文件: 默认开启,可以不设置 * 2. 映射文件: * 3. 实体类: 实现serializable接口 *

* 开发中经常不用二级缓存 * 1. 二级缓存数据主要在硬盘上 / 数据库的数据也在硬盘上 * 已经查好的数据 还得查 *

* 效率提升不明显 * 2. 以后用其他的技术代替mybatis 二级缓存(redis非关系型数据库) */ @Test public void test05() { //1. 模拟第一个用户查询 SqlSession session = MyBatisUtil.getSqlSession(); OrdersMapper mapper = session.getMapper(OrdersMapper.class); // 查询用户id=41的用户以及拥有的订单 User user = mapper.findUserByIdWithOrders(41); System.out.println(user); // 关闭第一个用户的查询 session MyBatisUtil.commitAndClose(session); //3. 模拟第二个用户查询(不同的SqlSession) SqlSession session2 = MyBatisUtil.getSqlSession(); OrdersMapper mapper2 = session2.getMapper(OrdersMapper.class); // 查询用户id=41的用户以及拥有的订单 User user2 = mapper2.findUserByIdWithOrders(41); System.out.println(user2); // 关闭第二个用户的查询 session MyBatisUtil.commitAndClose(session2); }

执行查看是否执行了两次SQL,如下:

image-20210406001217781

分析

二级缓存是mapper映射级别的缓存,多个SqlSession去操作同一个Mapper映射的sql语句,多个SqlSession可以共用二级缓存,二级缓存是跨SqlSession的。

二级缓存相比一级缓存的范围更大.

1589264629385

知识小结

1589203193705

1. mybatis的缓存,都不需要我们手动存储和获取数据。mybatis自动维护的。2. 使用mybatis,如果是中小型项目,使用自带缓存的机制是可以满足需求的。如果是大型(分布式)项目,mybatis的缓存灵活性不足,需要使用第三方的缓存技术解决问题。

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:5. Mybatis 单表查询 - resultMap标签 - 多条件查询 - 模糊查询
下一篇:11. MyBatis注解
相关文章

 发表评论

暂时没有评论,来抢沙发吧~