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. node - TypeError: argument handler must be a function 路由报错的原因

    原因 : 路由一定要暴露给外部使用   var express = require('express') var router = express.Router()   router.get('/', ...

  2. nginx的日志切换

    #touch /usr/local/nginx/sbin/cut_nginx_log.sh #chmod 755  /usr/local/nginx/sbin/cut_nginx_log.sh 下面是 ...

  3. bugku - pwn wp

    一. PWN1 题目:nc 114.116.54.89 10001 1.  直接kali里面跑nc 2.ls看看有啥 3.明显有一个flag cat查看一下 搞定 二 . PWN2 题目:给了nc 1 ...

  4. 148-PHP strip_tags函数,剥去字符串中的 HTML 标签(二)

    <?php //定义一段包含PHP代码的字符串 $php=<<<PHP 这里是PHP代码的开始 <?php echo "hello!"; PHP; $ ...

  5. 实体映射-------AutoMapper

    现在有2个实体(A.B),2个实体中的部分字段是相同的,现在把A实体获取的值赋值给B实体,利用AutoMapper实体映射可以轻松解决 参考 实体中不同名称之间的映射可以这样写 Mapper.Init ...

  6. JAVA - SpringBoot项目引用generator生成 Mybatis文件

    JAVA - SpringBoot项目引用generator生成 Mybatis文件  在spring官网https://start.spring.io/自动生成springboot项目,这里选择项目 ...

  7. 实验吧-杂项-你没有见过的加密!(php srand()和rand()函数)

    什么垃圾东西,弄半天,Windows上运行乱码,linux上7.3的php运行也是乱码(气死). 下载文件,查看内容 <?php function encrypt($str) { $crypte ...

  8. Sklearn 速查

    ## 版权所有,转帖注明出处 章节 SciKit-Learn 加载数据集 SciKit-Learn 数据集基本信息 SciKit-Learn 使用matplotlib可视化数据 SciKit-Lear ...

  9. spring boot 连接Mysql介绍

    Spring Boot 集成教程 Spring Boot 介绍 Spring Boot 开发环境搭建(Eclipse) Spring Boot Hello World (restful接口)例子 sp ...

  10. 第九篇 AJAX

    AJAX 阅读目录(Content) 概述 AJAX常见应用情景 AJAX的优缺点 jQuery实现的AJAX $.ajax参数 AJAX请求如何设置csrf_token 序列化 Django内置的s ...