MyBatis 缓存

文章源码

什么是缓存

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

Mybatis 中缓存分为一级缓存,二级缓存。

缓存的适用范围

适用范围:

  • 经常查询并且不经常改变的
  • 数据的正确与否对最终结果影响不大

一级缓存

它指的是 MyBatis 中 SqlSession 对象的缓存,当执行查询之后,查询的结果会同时存入到 SqlSession 会提供一块区域。该区域的结构是一个 Map,当再次查询同样的数据,MyBatis 会先去 SqlSession 中查询是否存在,如果有则直接拿出来使用。

当 SqlSession 对象消失时,MyBatis 的一级缓存也就消失了。

一级缓存的使用

  • 编写用户持久层 DAO 接口

        /**
    * 根据 ID 查询操作,使用一级缓存
    * @param id
    * @return
    */
    User findByIdCache(Integer id);
  • 编写用户持久层映射文件

        <select id="findByIdCache" resultType="USER" parameterType="java.lang.Integer">
    select * from user where id = #{id};
    </select>
  • 测试

        @Test
    public void findByIdCacheTest() {
    User user1 = userDAO.findByIdCache(41);
    System.out.println(user1.hashCode()); // 1439337960
    User user2 = userDAO.findByIdCache(41);
    System.out.println(user2.hashCode()); // 1439337960 System.out.println(user1 == user2); // true
    }

一级缓存的清空

    @Test
public void findByIdCacheClearTest() {
User user1 = userDAO.findByIdCache(41);
System.out.println(user1.hashCode()); // 1439337960 // 使缓存消失方法一:关闭 SqlSession 对象
// session.close(); // 使缓存消失方法二
session.clearCache(); // session = factory.openSession();
userDAO = session.getMapper(UserDAO.class); User user2 = userDAO.findByIdCache(41);
System.out.println(user2.hashCode()); // 315860201 System.out.println(user1 == user2); // false
}

一级缓存的分析

  • 一级缓存是 SqlSession 范围的缓存,当调用 SqlSession 的修改,添加,删除,commit()close() 等方法时,就会清空一级缓存。
  • 第一次发起查询用户 id 为 41 的用户信息,先去找缓存中是否有 id 为 41 的用户信息,如果没有,从数据库查询用户信息。
  • 得到用户信息,将用户信息存储到一级缓存中。
  • 如果 SqlSession 去执行 commit 操作(执行插入、更新、删除),清空 SqlSession 中的一级缓存,这样做的目的为了让缓存中存储的是最新的信息,避免脏读
  • 第二次发起查询用户 id 为 41 的用户信息,先去找缓存中是否有 id 为 41 的用户信息,缓存中有,直接从缓存中获取用户信息。

二级缓存

它指的是 MyBatis 中 SqlSessionFactory 对象的缓存,由同一个 SqlSessionFactory 对象创建的 SqlSession 共享其缓存。

二级缓存结构图

二级缓存的使用

  • 在 SqlMapConfig.xml 文件开启二级缓存

    <settings>
    <!-- 开启二级缓存的支持 -->
    <setting name="cacheEnabled" value="true"/>
    </settings>
  • 配置相关的 Mapper 映射文件

        <!-- 开启二级缓存的支持 -->
    <cache></cache>
  • 配置 statement 上面的 useCache 属性

        <select id="findByIdHighCache" resultType="USER" parameterType="java.lang.Integer" useCache="true">
    select * from user where id = #{id};
    </select>
  • 测试

        @Test
    public void findByIdHighCacheTest() {
    SqlSession sqlSession1 = factory.openSession();
    UserDAO dao1 = sqlSession1.getMapper(UserDAO.class);
    User user1 = dao1.findByIdHighCache(41);
    System.out.println(user1.hashCode()); // 765284253
    sqlSession1.close(); // 一级缓存消失 SqlSession sqlSession2 = factory.openSession();
    UserDAO dao2 = sqlSession2.getMapper(UserDAO.class);
    User user2 = dao2.findByIdHighCache(41);
    System.out.println(user2.hashCode()); // 1043351526
    sqlSession1.close(); // 一级缓存消失 System.out.println(user1 == user2); // false }

测试中执行了两次查询,并且在执行第一次查询后,关闭了一级缓存,再去执行第二次查询时,可以发现并没有对数据库发出 SQL 语句,所以此时的数据就只能是来自于所说的二级缓存。

练习和总结

【MyBatis】MyBatis 缓存的更多相关文章

  1. 通过源码分析MyBatis的缓存

    前方高能! 本文内容有点多,通过实际测试例子+源码分析的方式解剖MyBatis缓存的概念,对这方面有兴趣的小伙伴请继续看下去~ MyBatis缓存介绍 首先看一段wiki上关于MyBatis缓存的介绍 ...

  2. MyBatis 一级缓存与二级缓存

    MyBatis一级缓存 MyBatis一级缓存默认开启,一级缓存为Session级别的缓存,在执行以下操作时一级缓存会清空 1.执行session.clearCache(); 2.执行CUD操作 3. ...

  3. Mybatis学习记录(七)----Mybatis查询缓存

    1. 什么是查询缓存 mybatis提供查询缓存,用于减轻数据压力,提高数据库性能. mybaits提供一级缓存,和二级缓存. 一级缓存是SqlSession级别的缓存.在操作数据库时需要构造 sql ...

  4. 八 mybatis查询缓存(一级缓存,二级缓存)和ehcache整合

    1       查询缓存 1.1     什么是查询缓存 mybatis提供查询缓存,用于减轻数据压力,提高数据库性能. mybaits提供一级缓存,和二级缓存.

  5. MyBatis——Mybatis缓存

    原文:http://www.cnblogs.com/xdp-gacl/p/4270403.html MyBatis学习总结(七)--Mybatis缓存 一.MyBatis缓存介绍 正如大多数持久层框架 ...

  6. MyBatis一级缓存引起的无穷递归

    MyBatis一级缓存引起的无穷递归 引言: 最近在项目中参与了一个领取优惠劵的活动,当多个用户领取同一张优惠劵的时候,使用了数据库锁控制并发,起初的设想是:如果多个人同时领一张劵,第一个到达的人领取 ...

  7. Spring+SpringMVC+MyBatis深入学习及搭建(八)——MyBatis查询缓存

    转载请注明出处:http://www.cnblogs.com/Joanna-Yan/p/6956206.html 前面讲到:Spring+SpringMVC+MyBatis深入学习及搭建(七)——My ...

  8. 【MyBatis源码解析】MyBatis一二级缓存

    MyBatis缓存 我们知道,频繁的数据库操作是非常耗费性能的(主要是因为对于DB而言,数据是持久化在磁盘中的,因此查询操作需要通过IO,IO操作速度相比内存操作速度慢了好几个量级),尤其是对于一些相 ...

  9. mybatis一级缓存二级缓存

    一级缓存 Mybatis对缓存提供支持,但是在没有配置的默认情况下,它只开启一级缓存,一级缓存只是相对于同一个SqlSession而言.所以在参数和SQL完全一样的情况下,我们使用同一个SqlSess ...

  10. 深入浅出mybatis之缓存机制

    目录 前言 准备工作 MyBatis默认缓存设置 缓存实现原理分析 参数localCacheScope控制的缓存策略 参数cacheEnabled控制的缓存策略 总结 前言 提到缓存,我们都会不约而同 ...

随机推荐

  1. caffe源码 理解链式法则

    网络结构 首先我们抽象理解下一个网络结构是怎样的,如下图所示 F1,F2,F3为某种函数 input为输入数据,output为输出数据 X1,X2为为中间的层的输入输出数据 总体来说有以下关系 X1 ...

  2. 没有它你的DevOps是玩不转的,你信不?

    摘要:架构的选择对于DevOps的实践是至关重要的,从某种程度上来说,架构就是DevOps这场战役的粮草,它是支撑着DevOps成功落地的重要前提. 善用兵者,役不再籍,粮不三载.取用于国,因粮于敌, ...

  3. Mysql常用函数合集

    1. 字符函数 length(获取字节数,UTF-8编码中 一个汉字占3个字节,GBK编码中一个汉字占2个字节) select length('abc'); #结果:3 select length(' ...

  4. 精尽Spring MVC源码分析 - HandlerMapping 组件(二)之 HandlerInterceptor 拦截器

    该系列文档是本人在学习 Spring MVC 的源码过程中总结下来的,可能对读者不太友好,请结合我的源码注释 Spring MVC 源码分析 GitHub 地址 进行阅读 Spring 版本:5.2. ...

  5. Docker(七): 安装Loki

    洛基(Loki),是北欧神话中的恶作剧和谎言之神,亦是火神.他是巨人法布提(Farbauti)和女巨人劳菲(Laufey)的儿子,阿萨神族主神奥丁(Odin)的义兄弟,虽然他比奥丁要年轻许多.但他的个 ...

  6. Idea中Web项目Jsp文件找不到类解决方法

    在src下创建package,java代码放到包中,编译时才能在WEB-INFO的classes文件夹中生成可识别的class文件 https://blog.csdn.net/youwanname/a ...

  7. Kafka中使用Avro编码、解码消息

    1.消费者代码 import com.twitter.bijection.Injection; import com.twitter.bijection.avro.GenericAvroCodecs; ...

  8. Spark-6-如何缓解消除数据倾斜

    1 尽量避免数据源的数据倾斜 比如数据源是Kafka 以Spark Stream通过DirectStream方式读取Kafka数据为例.由于Kafka的每一个Partition对应Spark的一个Ta ...

  9. Impala的特点

    Impala的特点 0. 原理 基于内存的分析框架. 1.为什么会有Impala? hive进行计算太慢了,于是就有了Impala,Impala可以理解为是hive的内存版本. 2.Impala的优点 ...

  10. Java 持久层框架之 MyBatis

    MyBatis 简介 MyBatis 是一个基于 Java 的持久层框架,它内部封装了 JDBC,使开发者只需关注 SQL 语句本身,而不用再花费精力去处理诸如注册驱动.创建 Connection.配 ...