13.MyBatis缓存机制

1. 为什么使用缓存?

当用户频繁查询某些固定的数据时,第一次将这些数据从数据库中查询出来,保存在缓存中。当用户再次查询这些数据时,不用再通过数据库查询,而是去缓存里面查询。减少网络连接和数据库查询带来的损耗,从而提高我们的查询效率,减少高并发访问带来的系统性能问题。

一句话概括:经常查询一些不经常发生变化的数据,使用缓存来提高查询效率。

像大多数的持久化框架一样,Mybatis也提供了缓存策略,通过缓存策略来减少数据库的查询次数,从而提高性能。 Mybatis中缓存分为一级缓存,二级缓存。

2.一级缓存

一级缓存是SqlSession级别的缓存,是默认开启的。

  • 所以在参数和SQL完全一样的情况下,我们使用同一个SqlSession对象调用一个Mapper方法,往往只执行一次SQL,因为使用SelSession第一次查询后,MyBatis会将其放在缓存中,以后再查询的时候,如果没有声明需要刷新并且缓存没有超时的情况下,SqlSession都会取出当前缓存的数据,而不会再次发送SQL到数据库。

2.1 验证

 /*** 根据id查询用户* @throws IOException*/@Testpublic void test8() throws IOException {InputStream resourceAsStream = Resources.getResourceAsStream("SqlMapConfig.xml");SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);SqlSession sqlSession = sqlSessionFactory.openSession();UserMapper userMapper = sqlSession.getMapper(UserMapper.class);User user = userMapper.findUserById(1);System.out.println(user);User user1 = userMapper.findUserById(1);System.out.println(user);sqlSession.close();}

我们可以发现,虽然在上面的代码中我们查询了两次,但最后只执行了一次数据库操作,这就是Mybatis提供给我们的一级缓存在起作用了。因为一级缓存的存在,导致第二次查询id为1的记录时,并没有发出sql语句从数据库中查询数据,而是从一级缓存中查询。结果如图所示:

2.2 分析

  • 一级缓存是SqlSession范围的缓存,执行SqlSession的C(增加)U(更新)D(删除)操作,或者调用clearCache()、commit()、close()方法,都会清空缓存。

  1. 第一次查询用户id为1的用户信息,先去缓存中查找id为1的用户信息,如果没有,从数据库查询用户信息。
  2. 得到用户信息,将用户信息存储到一级缓存中(sqlSession缓存区域)
  3. 如果执行SqlSession的C(增加)U(更新)D(删除)操作,或者调用clearCache()、commit()、close()方法,都会清除缓存。如果没有清除缓存,在同一个sqlSession对象调用同一个Mapper方法,会去一级缓存中查找之前查找过的数据,而不用去数据库重新查找。

2.3清除缓存

sqlSession.clearCache();

 @Testpublic void test8() throws IOException {InputStream resourceAsStream = Resources.getResourceAsStream("SqlMapConfig.xml");SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);SqlSession sqlSession = sqlSessionFactory.openSession();UserMapper userMapper = sqlSession.getMapper(UserMapper.class);User user = userMapper.findUserById(1);System.out.println(user);//手动清除缓存sqlSession.clearCache();User user1 = userMapper.findUserById(1);System.out.println(user);sqlSession.close();}

此时回执行两遍sql,结果如图:

此外也可以在xml映射文件,设置每次执行都会清除缓存。

<!-- 每次查询时,都会清除缓存 -->
< select flushCache="true"></select>

3.二级缓存

3.1二级缓存介绍

  1. 二级缓存是namespace级别(跨sqlsession)的缓存,是默认不开启的。
  2. 二级缓存的开启需要进配置,实现二级缓存的时候,MyBatis要求返回的POJO必须是可序列化的,也就是实现Serializable接口。
  3. 只需要在映射XML文件配置,就可以开启二级缓存。

3.2验证

(1)配置核心配置文件

<settings><!--
因为cacheEnabled的取值默认就为true,所以这一步可以省略不配置。
为true代表开启二级缓存;为false代表不开启二级缓存。--><setting name="cacheEnabled" value="true"/>
</settings>

(2)配置UserMapper.xml映射

<mapper namespace="com.lagou.dao.UserMapper"><!--当前映射文件开启二级缓存--><cache></cache><!--
<select>标签中设置useCache=”true”代表当前这个statement要使用二级缓存。
如果不使用二级缓存可以设置为false注意:针对每次查询都需要最新的数据sql,要设置成useCache="false",禁用二级缓存。
--><select id="findById" parameterType="int" resultType="user" useCache="true"
>SELECT * FROM `user` where id = #{id}</select>
</mapper>

(3)修改实体类

public class User implements Serializable {private Integer id;private String username;private Date birthday;private String sex;private String address;private List<Role> roleList;private List<Order> orderList;
}

(4)测试结果

@Test
public void testTwoCache() throws Exception {SqlSession sqlSession = MyBatisUtils.openSession();UserMapper userMapper = sqlSession.getMapper(UserMapper.class);User user = userMapper.findById(41);System.out.println("第一次查询的用户:" + user);sqlSession.close();SqlSession sqlSession1 = MyBatisUtils.openSession();UserMapper userMapper1 = sqlSession1.getMapper(UserMapper.class);User user1 = userMapper1.findById(41);System.out.println("第二次查询的用户:"+user1);sqlSession1.close();
}

3.3二级缓存分析

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

引入二级缓存会带来的问题

  • mybatis的二级缓存因为是namespace级别,所以在进行多表查询时会产生脏读问题

需求:查询用户信息及用户关联的订单信息金额(关联两张表user、order表)

分析:

  1. 第一次查询出用户信息的金额:199元
  2. 第二次查询,会在二级缓存区域获得数据,金额依然为:199元
  3. 现在去更新order表用户所对应的订单金额,修改为:299元
  4. 现在就出现非常严重的脏读问题!!!
    1. 因为去修改order表的数据,是操作orderMapper.xml,所以只清除的是orderMapper.xml的缓存。UserMapper.xml的缓存依然存在,所以脏数据依然存在。
  • 实际开发会使用第三方缓存,例如rides.

4.小结

  1. mybatis的缓存,都不需要我们手动存储和获取数据。mybatis自动维护的。
  2. mybatis开启了二级缓存后,那么查询顺序:二级缓存–》一级缓存–》数据库
  3. 注意:mybatis的二级缓存会存在脏读问题,需要使用第三方的缓存技术解决问题。

13.MyBatis缓存机制相关推荐

  1. MyBatis复习笔记6:MyBatis缓存机制

    MyBatis缓存机制 MyBatis 包含一个非常强大的查询缓存特性,它可以非常方便地配置和定制.缓存可以极大的提升查询效率. MyBatis系统中默认定义了两级缓存. 一级缓存和二级缓存. 默认情 ...

  2. 【转】MyBatis缓存机制

    转载:https://blog.csdn.net/bjweimengshu/article/details/79988252. 本文转载自公众号 美团技术点评 前言 MyBatis是常见的Java数据 ...

  3. MyBatis缓存机制之一级缓存

    MyBatis缓存机制之一级缓存 前言 MyBatis内部封装了JDBC,简化了加载驱动.创建连接.创建statement等繁杂的过程,是我们常见的持久性框架.缓存是在计算机内存中保存的临时数据,读取 ...

  4. [Professor麦]深入剖析Mybatis缓存机制

    哈哈哈,终于考完试了,用了大概两天时间肝了这篇文章!!! 关于今天要讲的mybatis缓存机制,其实之前我已经有看过也用过,只不过平常不太留意,最近在看mybatis源码,就来讲一下这个缓存机制 前言 ...

  5. 《深入理解mybatis原理》 MyBatis缓存机制的设计与实现

    本文主要讲解MyBatis非常棒的缓存机制的设计原理,给读者们介绍一下MyBatis的缓存机制的轮廓,然后会分别针对缓存机制中的方方面面展开讨论. MyBatis将数据缓存设计成两级结构,分为一级缓存 ...

  6. 五、mybatis缓存机制

    文章目录 五.缓存机制 一级缓存(默认开启) 二级缓存 注意 缓存顺序 mybatis基础教程[5小时36讲全套] 五.缓存机制 一级缓存(默认开启) ​ 同一个sqlsession会话对象,执行同样 ...

  7. MyBatis缓存机制学习

    与Hibernate一样,MyBatis 同样提供了一级缓存和二级缓存的支持. 一级缓存: 基于PerpetualCache 的 HashMap本地缓存,其存储作用域为 Session,当 Sessi ...

  8. Mybatis缓存机制理解及配置

    2019独角兽企业重金招聘Python工程师标准>>> 1.     Ehcache EHCache是来自sourceforge(http://ehcache.sourceforge ...

  9. mybatis缓存机制

    文章目录 缓存介绍 一级缓存 二级缓存 二级缓存使用步骤 二级缓存和一级缓存的区别: 缓存介绍 缓存主要是对查询起作用,减轻数据库的压力,提高数据库的性能 mybatis中提供了一级缓存.二级缓存 一 ...

最新文章

  1. 160个Crackme045
  2. 幽灵交易策略_源码 | 幽灵交易者策略
  3. Akamai首席架构师Will:WebRTC、QUIC、DASH、AV1都前景可观
  4. Flutter项目实战教程分享、基础使用、性能优化、每日积累
  5. 【已解决】Protocol ‘https‘ not on whitelist ‘file,crypto,data‘!
  6. python 生成器和迭代器介绍
  7. 使用Monit监控进程与系统状态
  8. 第四节:EasyUI的一些操作
  9. uclient uc oracle,UClient下载
  10. 树莓派人脸识别源代码
  11. android 模拟gps坐标,Android系统中模拟GPS位置
  12. 于歆杰pdf 电路原理_电路原理于歆杰答案pdf
  13. Android源码下载repo以及repo init总结
  14. 显著性水平与p值的区别
  15. 【软件设计师】知识点总结
  16. 数据压缩_任务五_预测误差均方值推导及最小二乘法
  17. hive删除EXTERNAL外表
  18. 【ROS1】LeGO-LOAM-BOR简洁复现过程
  19. Bellman Equation 贝尔曼方程
  20. 节假日读取接口_节假日API接口,2018年,直接计算好的

热门文章

  1. 我,30岁,放弃国企稳定的工作,转行数据分析,老婆要和我离婚
  2. c# 身份证读取 神思第二代居民身份证验证机具接口函数说明__版本 V2.6.2 2017-12-20
  3. 医疗信息化资源(1)
  4. vscode头文件波浪号,函数无法补全问题
  5. cache-主存的三种映射方式
  6. 商品服务(SKU、下单流程、购物车、优惠券设计)
  7. unity实现牧师与魔鬼2.0(动作分离版) 基本操作演练
  8. HTML thead tbody tfood
  9. 〖大前端 - 基础入门三大核心之CSS篇⑱〗- CSS中的背景
  10. excel自带有vba手册吗_EXCELVBA完全手册.pdf