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. REHの个人主页

    朝暮与年岁并往 然后与你一同行至天光. 简介 这是怎么做到的啊-- 把那些迷茫的浑浊的不可预知的,裁剪,变化,像个造物主一样,最终成为混沌而又分明的,除去一身的戾气和险恶,把那些复杂和晦涩都剖析成它精 ...

  2. CF500G / T148321 走廊巡逻

    题目链接 这题是 Codeforces Goodbye 2014 的最后一题 CF500G,只是去掉了 \(u \not= x, v \not = v\) 的条件. 官方题解感觉有很多东西说的迷迷瞪瞪 ...

  3. 题解-[ZJOI2005]沼泽鳄鱼

    题解-[ZJOI2005]沼泽鳄鱼 前置知识: 邻接矩阵 矩阵乘法 矩阵快速幂 [ZJOI2005]沼泽鳄鱼 给一个有 \(N\) 个点,\(M\) 条双向边的图 \(G\),其中有 \(NFish\ ...

  4. 题解-CF1140E Palindrome-less Arrays

    CF1140E Palindrome-less Arrays \(n\) 和 \(k\) 和 \(n\) 个数的序列 \(a\).把 \(a\) 中的 \(-1\) 替换成 \([1,k]\) 之间的 ...

  5. 如何理解group by语句

    参考文章: https://blog.csdn.net/hao1066821456/article/details/69556644 如何实现一对多关系,得到一行多列的显示方式: group by可以 ...

  6. JavaScript中遍历的几种方法

    1.while循环 while后面跟循环条件和执行语句,只要满足条件,就会一直执行里面的执行 var i = 0 while(){ console.log(i) i++ } 2.do...while循 ...

  7. oracle 11g打补丁错误(Missing command :fuser)

    在给oracle 11g数据库打补丁的时候出现以下错误: [oracle@node01 31537677]$ $ORACLE_HOME/OPatch/opatch apply Oracle Inter ...

  8. Missing Private key解决方案——IOS证书 .cer 以p12文件以及配置方案

    一个苹果证书怎么多次使用--导出p12文件 为什么要导出.p12文件 因为苹果规定 .cer证书只能存在于一台机器上,因此 如果另一台电脑想要用的话,需要导出为.p12 file ,安装到另一台没有安 ...

  9. [日常摸鱼]bzoj1968 [Ahoi2005]COMMON 约数研究

    题意:记$f(n)$为$n$的约数个数,求$\sum_{i=1}^n f(i)$,$n \leq 10^6$. 我也不知道为什么我要来做这个- 直接枚举每个数会是哪些数的约数-复杂度$O(n log ...

  10. Eureka系列(二) 服务注册Server端具体实现

    服务注册 Server端流程   我们先看下面这张图片,这张图片简单描述了下我们EurekaClient 在调用EurekaServer 提供的服务注册Http接口,Server端实现接口执行的大致流 ...