MyBatis的缓存指的是缓存查询结果,当以后使用相同的sql语句、传入相同的参数进行查询时,可直接从mybatis本地缓存中获取查询结果,而不必查询数据库。

mybatis的缓存包括一级缓存、二级缓存,一级缓存默认是开启的,二级缓存默认是关闭的。

一级缓存:

SqlSession级别,在SqlSession中有一个Map,key是由sql语句、参数等信息组成的唯一值,value是查询出来的结果对象。

二级缓存:

mapper级别,同一个namespace下的mapper,有一个Map。

二级缓存可以使这些sqlSession做到查询结果共享。


一级缓存

一级缓存默认是开启的。

        User user1 = mapper.queryUserById(1);
User user2 = mapper.queryUserById(1);

第一次查询时,就将查询结果放到一级缓存中。

如果后续使用的sql语句相同、传入的实参也相同,则结果对象也会相同,直接从一级缓存中获取结果对象,不再查询数据库。

        User user1 = mapper.queryUserById(1);
sqlSession.commit();
User user2 = mapper.queryUserById(1);

如果此sqlSession调用了commit()方法,会自动清空此sqlSession的一级缓存。

因为使用commit(),会将修改提交到数据库,下一次相同的查询,查询结果可能变了,之前的一级缓存不能再用,所以会自动清空。

     User user1 = mapper.queryUserById(1);

        HashMap<String, Object> map = new HashMap<>();
map.put("username", "张三");
map.put("id", 1);
mapper.updateUser(map); User user2 = mapper.queryUserById(1);

事实上,只要此sqlSession调用了<update>、<insert>、<delete>这些会修改数据库的元素,就会清空此sqlSession的一级缓存,不管有没有使用commit()提交。


二级缓存

     SqlSession sqlSession1 = MyBatisUtils.getSqlSession();
UserMapper mapper1 = sqlSession1.getMapper(UserMapper.class);
User user1 = mapper1.queryUserById(1);
System.out.println(user1); SqlSession sqlSession2 = MyBatisUtils.getSqlSession();
UserMapper mapper2 = sqlSession2.getMapper(UserMapper.class);
User user2 = mapper2.queryUserById(1);
System.out.println(user2);

不使用二级缓存,会执行2次查询。

二级缓存的使用步骤,此处以UserMapper为例:

(1)pojo类要是可序列化的

public class User implements Serializable {
//......
}

(2)在mybatis全局配置文件中开启二级缓存

<settings>
<setting name="logImpl" value="LOG4J"/>
<setting name="cacheEnabled" value="true"/>
</settings>

二级缓存默认是关闭的,需要手动开启。

(3)在mapper映射文件中指定二级缓存的实现方式,必须显式指定

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC
"-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.chy.mapper.UserMapper">
<cache />
<select id="queryUserById" parameterType="integer" resultType="user">
SELECT * FROM user_tb WHERE id=#{id}
</select>
<update id="updateUser" parameterType="hashmap">
UPDATE user_tb SET username=#{username} WHERE id=#{id}
</update>
</mapper>

完整写法:

<cache type="perpetualCache" />

type指定二级缓存的实现方式,缺省type时默认使用mybatis自带的perpetualCache。

(4)需要调用close()关闭sqlSession,才会将此sqlSession的查询结果(一级缓存)写入到二级缓存中

     SqlSession sqlSession1 = MyBatisUtils.getSqlSession();
UserMapper mapper1 = sqlSession1.getMapper(UserMapper.class);
User user1 = mapper1.queryUserById(1);
System.out.println(user1);
sqlSession1.close(); SqlSession sqlSession2 = MyBatisUtils.getSqlSession();
UserMapper mapper2 = sqlSession2.getMapper(UserMapper.class);
User user2 = mapper2.queryUserById(1);
System.out.println(user2);

只执行1次查询。后续使用相同sql语句、传入相同的实参进行查询时,直接从二级缓存中获取结果对象。

提交修改时,会清空整个二级缓存:

     SqlSession sqlSession1 = MyBatisUtils.getSqlSession();
UserMapper mapper1 = sqlSession1.getMapper(UserMapper.class);
User user1 = mapper1.queryUserById(1);
System.out.println(user1); HashMap<String, Object> hashMap = new HashMap<>();
hashMap.put("username", "j");
hashMap.put("id", 1);
mapper1.updateUser(hashMap);
sqlSession1.commit(); SqlSession sqlSession2 = MyBatisUtils.getSqlSession();
UserMapper mapper2 = sqlSession2.getMapper(UserMapper.class);
User user2 = mapper2.queryUserById(2);
System.out.println(user2);

只写了commit()、实际没有调用<insert> | <update> | <delete>,不会清空二级缓存,反而会将之前查询结果写入到二级缓存。

写了commit()、有调用<insert> | <update> | <delete>,会清空整个二级缓存。

先后调用commit()、close(),不会写入二级缓存,因为commit()的存在,反而会清空整个二级缓存。

MyBatis 查询结果的缓存的更多相关文章

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

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

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

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

  3. 【JAVA - SSM】之MyBatis查询缓存

    为了减轻数据压力,提高数据库的性能,我们往往会需要使用缓存.MyBatis为我们提供了一级缓存和二级缓存. (1)一级缓存是SqlSession级别的缓存,在操作数据库的时候需要创建一个SqlSess ...

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

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

  5. mybatis查询缓存——(十三)

    1.     mybatis缓存介绍 如下图,是mybatis一级缓存和二级缓存的区别图解: mybatis提供查询缓存,用于减轻数据压力,提高数据库性能. mybaits提供一级缓存,和二级缓存.

  6. mybatis查询缓存

    一级缓存针对每个sqlSession进行缓存,sqlSession销毁,一级缓存就不存在. ,使用Map存储了sql执行查询结果集(java对象) 二级缓存针对每个map的namespace进行缓存. ...

  7. apache ignite系列(九):使用ddl和dml脚本初始化ignite并使用mybatis查询缓存

    博客又断了一段时间,本篇将记录一下基于ignite对jdbc支持的特性在实际使用过程中的使用. 使用ddl和dml脚本初始化ignite 由于spring-boot中支持通过spring.dataso ...

  8. 【JavaEE】之MyBatis查询缓存

    为了减轻数据压力,提高数据库的性能,我们往往会需要使用缓存.MyBatis为我们提供了一级缓存和二级缓存. (1)一级缓存是SqlSession级别的缓存,在操作数据库的时候需要创建一个SqlSess ...

  9. MyBatis 延迟加载,一级缓存,二级缓存设置

    什么是延迟加载 resultMap中的association和collection标签具有延迟加载的功能. 延迟加载的意思是说,在关联查询时,利用延迟加载,先加载主信息.使用关联信息时再去加载关联信息 ...

随机推荐

  1. netty权威指南学习笔记一——NIO入门(3)NIO

    经过前面的铺垫,在这一节我们进入NIO编程,NIO弥补了原来同步阻塞IO的不足,他提供了高速的.面向块的I/O,NIO中加入的Buffer缓冲区,体现了与原I/O的一个重要区别.在面向流的I/O中,可 ...

  2. 1 —— js 语法回顾 —— 数据类型。流程控制。数组

    一,数据类型 字符串 . 数值 .布尔. null . undefined . 对象  ( 数组 . 函数 function(){} . object) undefined 出现的情景 :  (1)变 ...

  3. redis报错MISCONF Redis is configured to save RDB snapshots, but is currently not able to persist

    解决方法:通过redis-cli连接到服务器后执行以下命令: config set stop-writes-on-bgsave-error no 注意:这种方法只是忽略了问题,并没有解决问题,具体问题 ...

  4. 119-PHP调用private成员的方法

    <?php class ren{ //定义人类 private $birthday='1990-12-20'; //定义private修饰的成员属性 public function say_bi ...

  5. postgrepSQL数据库创建二级分区表

    数据库版本:version 10 以非继承的形式创建分区表,一级分区是城市,二级分区是天:指定分区有两种形式,RANGE和LIST,如果使用RANGE在创建分区语句中是通过FOR VALUES FRO ...

  6. NumPy 数组切片

    章节 Numpy 介绍 Numpy 安装 NumPy ndarray NumPy 数据类型 NumPy 数组创建 NumPy 基于已有数据创建数组 NumPy 基于数值区间创建数组 NumPy 数组切 ...

  7. ACM-AK吧!少年

    题目描述:AK吧!少年 AK is an ACM competition finished all of the problems. AC This problem is one of the ste ...

  8. com.alibaba.druid.pool.DruidDataSource

    https://www.cnblogs.com/wuyun-blog/p/5679073.html DRUID介绍 DRUID是阿里巴巴开源平台上一个数据库连接池实现,它结合了C3P0.DBCP.PR ...

  9. 每天一点点之css - 动画-一个圆绕着另一个圆动(绕着轨迹运动)

    最近要开发一个类似星河的效果,需要小圆绕着一定的轨迹运动,这个时候我首先想到的是使用canvas来实现,在实现过程中发现这个实现起来不是很灵活,然后想到css3有动画也可以实现,下面是效果 注:图2是 ...

  10. 用Spring中的ResponseEntity文件批量压缩下载

    我看了很多网上的demo,先生成ZIP压缩文件,然后再下载. 我这里是生成ZIP文件流 进行下载.(核心代码没多少,就是一些业务代码) @RequestMapping(value = "/& ...