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. Mysql自动备份与还原 转

    Mysql自动备份与还原 一.自动备份:将以下代码保存为*.bat批处理脚本,然后再添加Windows定时作业,如每天凌晨2点执行:set s=%date:~0,4%%date:~5,2%%date: ...

  2. oracle分组后取某组中最大的值

    查询username,根据fundcode分组,按照date倒序,取date最大的一条数据 select * from ( select username, row_number() over(par ...

  3. 记一次docker使用异常

    背景: win10 docker 有几天没有用Oracle数据库,突然发现数据库挂了 docker start oracle 报错 具体错误信息: Error starting userland pr ...

  4. java_05_IO

    java_05_IO 1,动手动脑 使用Files. walkFileTree()找出指定文件夹下所有大于指定大小(比如1M)的文件. 分析思路: 1)找到该文件夹下所有文件. 2)找出其中字节数大于 ...

  5. 2016蓝桥杯省赛C/C++A组第七题 剪邮票(暴力+并查集)

    题意:有12张连在一起的12生肖的邮票.现在你要从中剪下5张来,要求必须是连着的.(仅仅连接一个角不算相连) 分析:暴力+并查集. 1.记录下每个数字所在位置. 2.先枚举各不相同的5个数的所有可能情 ...

  6. tx2的一些系统命令

    查看TX2 ubuntu系统版本命令:https://blog.csdn.net/zhengxiangwen/article/details/60324802 sudo uname --m

  7. ssi引用路径规则

    1.file:引用的是相对路径,相对当前文件的,特别注意使用file,被引用文件只能与当前文件同级.或下级.不能在其上级(不支持../) <!--#include file="head ...

  8. js运用sort对json 数组进行排序

    Array.sort()方法是用来对数组项进行排序的 ,默认情况下是进行升序排列.sort() 方法可以接受一个 方法为参数. sort()排序时每次比较两个数组项都回执行这个参数,并把两个比较的数组 ...

  9. HZNU-ACM寒假集训Day4小结 最短路

    最短路 1.Floy 复杂度O(N3)  适用于任何图(不存在负环) 模板 --kuangbin #include<iostream> #include<cstdio> #in ...

  10. CSS的Flex弹性布局概念

    1.Flex概念: Flex是Flexible Box的缩写,顾名思义为“弹性布局”,用来为盒装模型提供最大的灵活性. 任何一个容器都可以指定为Flex 布局. 设为flex布局以后,子元素的floa ...