app开发者平台在数字化时代的重要性与发展趋势解析
734
2022-11-21
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
/** * 一级缓存: 默认开启 * * 缓存失效: * 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. 映射文件:
* 开发中经常不用二级缓存 * 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小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~