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. CF1373F Network Coverage

    题目链接 对于每一个 \(i\) 可以看作一个管道.赋予三个信息: \(\text{minIn}_i\) 表示至少要从上一家 \(i - 1\) 得到连接数,才能正常供给 \(i\) 城市 \(\te ...

  2. linux tar 压缩和解压缩

    tar -c: 建立压缩档案-x:解压-t:查看内容-r:向压缩归档文件末尾追加文件-u:更新原压缩包中的文件 这五个是独立的命令,压缩解压都要用到其中一个,可以和别的命令连用但只能用其中一个. 下面 ...

  3. C++ 消失的析构函数 —— virtual 实现的动态析构

    在C++类的结构中可以使用类方法创建内存,使用类的析构函数去施放内存,但有这么一种情况会导致:即使在析构函数中释放了内存,但由于析构函数没有被调用而导致内存泄漏,如下代码. 1 #include &l ...

  4. sql注入之文件写入into outfile

    sql注入中写入webshell的几种方式 sql注入中写入webshell的几种方式 secure_file_priv="c:/-"被注释掉或者是web路径 php.ini中的g ...

  5. Spring Boot 启动事件和监听器,太强大了!

    大家都知道,在 Spring 框架中事件和监听无处不在,打通了 Spring 框架的任督二脉,事件和监听也是 Spring 框架必学的核心知识之一. 一般来说,我们很少会使用到应用程序事件,但我们也不 ...

  6. remmina 软件rdp协议链接windows失败

    remmina 1.42  链接 win10 提示失败......其他版本win还没有测试过. 忘记了在那个论坛有是说加密问题,照着改确实可以.具体原因是默认设置加密方式这一项不知道为什么不起作用,手 ...

  7. Hbase系列文章

    Hbase系列文章 HBase(一): c#访问hbase组件开发 HBase(二): c#访问HBase之股票行情Demo HBase(三): Azure HDInsigt HBase表数据导入本地 ...

  8. 微服务之间如何共享DTO?

    1. 概述 近些年来,微服务变得越来越流行.微服务基本特征是模块化.独立.易于扩展的.它们之间需要协同工作并交换数据.为了实现这一点,我们创建了名为 DTO 的共享数据传输对象.在本文中,我们将介绍在 ...

  9. 前中后序递归遍历树的体会 with Python

    前序:跟->左->右 中序:左->根->右 后序:左>右->根 采用递归遍历时,编译器/解释器负责将递归函数调用过程压入栈并保护现场,在不同位置处理根节点即可实现不 ...

  10. mssql不存在便插入存在不执行操作

    前言 参考:https://www.jb51.cc/mssql/76911.html 在mssql中,在记录不存在时插入记录,如果存在则不执行操作 数据库 相关语句 --创建表 CREATE TABL ...