MyBatis缓存通俗易懂
1.1 mybatis缓存介绍
如下图,是mybatis一级缓存和二级缓存的区别图解:

Mybatis一级缓存的作用域是同一个SqlSession,在同一个sqlSession中两次执行相同的sql语句,第一次执行完毕会将数据库中查询的数据写到缓存(内存),第二次会从缓存中获取数据将不再从数据库查询,从而提高查询效率。当一个sqlSession结束后该sqlSession中的一级缓存也就不存在了。当遇到增删改时会清空缓存。Mybatis默认开启一级缓存。
Mybatis二级缓存是多个SqlSession共享的,其作用域是mapper的同一个namespace,不同的sqlSession两次执行相同namespace下的sql语句且向sql中传递参数也相同即最终执行相同的sql语句,第一次执行完毕会将数据库中查询的数据写到缓存(内存),第二次会从缓存中获取数据将不再从数据库查询,从而提高查询效率。当遇到增删改时会清空缓存。Mybatis默认没有开启二级缓存需要在setting全局参数中配置开启二级缓存。
1.2 一级缓存
1.2.1 原理
下图是根据id查询用户的一级缓存图解:

一级缓存区域是根据SqlSession为单位划分的。
每次查询会先从缓存区域找,如果找不到从数据库查询,查询到数据将数据写入缓存。
Mybatis内部存储缓存使用一个HashMap,key为hashCode+sqlId+Sql语句。value为从查询出来映射生成的java对象
sqlSession执行insert、update、delete等操作commit提交后会清空缓存区域。
1.2.2 测试1
//获取session
       SqlSession session = sqlSessionFactory.openSession();
       //获限mapper接口实例
       UserMapper userMapper = session.getMapper(UserMapper.class);
       //第一次查询
       User user1 = userMapper.findUserById();
       System.out.println(user1);
//第二次查询,由于是同一个session则不再向数据发出语句直接从缓存取出
       User user2 = userMapper.findUserById();
       System.out.println(user2);
//关闭session
       session.close();
1.2.3 测试2
//获取session
       SqlSession session = sqlSessionFactory.openSession();
       //获限mapper接口实例
       UserMapper userMapper = session.getMapper(UserMapper.class);
       //第一次查询
       User user1 = userMapper.findUserById();
       System.out.println(user1);
       //在同一个session执行更新
       User user_update = new User();
       user_update.setId();
       user_update.setUsername("李奎");
       userMapper.updateUser(user_update);
       session.commit();
       //第二次查询,虽然是同一个session但是由于执行了更新操作session的缓存被清空,这里重新发出sql操作
       User user2 = userMapper.findUserById();
       System.out.println(user2);
1.3 二级缓存
1.3.1 原理
下图是多个sqlSession请求UserMapper的二级缓存图解。

二级缓存区域是根据mapper的namespace划分的,相同namespace的mapper查询数据放在同一个区域,如果使用mapper代理方法每个mapper的namespace都不同,此时可以理解为二级缓存区域是根据mapper划分。
每次查询会先从缓存区域找,如果找不到从数据库查询,查询到数据将数据写入缓存。
Mybatis内部存储缓存使用一个HashMap,key为hashCode+sqlId+Sql语句。value为从查询出来映射生成的java对象
sqlSession执行insert、update、delete等操作commit提交后会清空缓存区域。
1.3.2 开启二级缓存:
在核心配置文件SqlMapConfig.xml中加入
<setting name="cacheEnabled" value="true"/>
| 描述 | 允许值 | 默认值 | |
| cacheEnabled | 对在此配置文件下的所有cache 进行全局性开/关设置。 | true false | true | 
要在你的Mapper映射文件中添加一行: <cache /> ,表示此mapper开启二级缓存。
1.3.3 实现序列化
二级缓存需要查询结果映射的pojo对象实现java.io.Serializable接口实现序列化和反序列化操作,注意如果存在父类、成员pojo都需要实现序列化接口。
public class Orders implements Serializable
public class User implements Serializable
....
1.3.4 测试
//获取session1
       SqlSession session1 = sqlSessionFactory.openSession();
       UserMapper userMapper = session1.getMapper(UserMapper.class);
       //使用session1执行第一次查询
       User user1 = userMapper.findUserById();
       System.out.println(user1);
       //关闭session1
       session1.close();
       //获取session2
       SqlSession session2 = sqlSessionFactory.openSession();
       UserMapper userMapper2 = session2.getMapper(UserMapper.class);
       //使用session2执行第二次查询,由于开启了二级缓存这里从缓存中获取数据不再向数据库发出sql
       User user2 = userMapper2.findUserById();
       System.out.println(user2);
       //关闭session2
       session2.close();
1.3.5 禁用二级缓存
在statement中设置useCache=false可以禁用当前select语句的二级缓存,即每次查询都会发出sql去查询,默认情况是true,即该sql使用二级缓存。
<select id="findOrderListResultMap" resultMap="ordersUserMap" useCache="false">
1.3.6 刷新缓存
在mapper的同一个namespace中,如果有其它insert、update、delete操作数据后需要刷新缓存,如果不执行刷新缓存会出现脏读。
设置statement配置中的flushCache="true" 属性,默认情况下为true即刷新缓存,如果改成false则不会刷新。使用缓存时如果手动修改数据库表中的查询数据会出现脏读。
如下:
<insert id="insertUser" parameterType="cn.itcast.mybatis.po.User" flushCache="true">
MyBatis缓存通俗易懂的更多相关文章
- mybatis缓存
		mybatis缓存http://www.cnblogs.com/QQParadise/articles/5109633.htmlhttp://www.mamicode.com/info-detail- ... 
- Mybatis缓存处理机制
		一.MyBatis缓存介绍 正如大多数持久层框架一样,MyBatis 同样提供了一级缓存和二级缓存的支持 一级缓存: 基于PerpetualCache 的 HashMap本地缓存,其存储作用域为 Se ... 
- MyBatis缓存禁用失败
		问题:MyBatis缓存无法禁用,同一个session的select查询结果一样,但是数据库其实已改变. 尝试达到想要的目的: 1.msgmapper.xml里的select标签加上 <sele ... 
- MyBatis入门学习教程-MyBatis缓存
		一.MyBatis缓存介绍 正如大多数持久层框架一样,MyBatis 同样提供了 package me.gacl.test; 2 import me.gacl.domain.User; import ... 
- MyBatis学习总结(七)——Mybatis缓存(转载)
		孤傲苍狼 只为成功找方法,不为失败找借口! MyBatis学习总结(七)--Mybatis缓存 一.MyBatis缓存介绍 正如大多数持久层框架一样,MyBatis 同样提供了一级缓存和二级缓存的 ... 
- MyBatis学习总结(七)——Mybatis缓存
		一.MyBatis缓存介绍 正如大多数持久层框架一样,MyBatis 同样提供了一级缓存和二级缓存的支持 一级缓存: 基于PerpetualCache 的 HashMap本地缓存,其存储作用域为 Se ... 
- MyBatis学习总结(七)——Mybatis缓存
		一.MyBatis缓存介绍 正如大多数持久层框架一样,MyBatis 同样提供了一级缓存和二级缓存的支持 一级缓存: 基于PerpetualCache 的 HashMap本地缓存,其存储作用域为 Se ... 
- MyBatis——Mybatis缓存
		原文:http://www.cnblogs.com/xdp-gacl/p/4270403.html MyBatis学习总结(七)--Mybatis缓存 一.MyBatis缓存介绍 正如大多数持久层框架 ... 
- 【转】MyBatis学习总结(七)——Mybatis缓存
		[转]MyBatis学习总结(七)——Mybatis缓存 一.MyBatis缓存介绍 正如大多数持久层框架一样,MyBatis 同样提供了一级缓存和二级缓存的支持 一级缓存: 基于PerpetualC ... 
随机推荐
- Struts2的优点与Struts1的区别:
			单实例与多实例有状态就是有数据存储功能,比如购物车,买一件东西放进去,可以再次购买或者删减.无状态就是一次操作,不能保存数据. 有状态对象,就是有成员属性的对象,可以保存数据,是非线程安全的.无状态对 ... 
- jmeter结果分析(图形报表和聚合报告)
			采用Jmeter测试工具对web系统作的负载测试,得出的响应报表,数据比较难懂,现作一具体说明.以下是在一次具体负载测试中得出的具体数值,测试线程设置情况为:线程数:200,等待时间(ramp-up) ... 
- Hadoop完全分布式搭建
			---记于2015年11月6日星期五 准备工作 软硬件环境 主机操作系统:处理器:i5,主频:3.2G,内存:8G,Windows64 虚拟机软件:VMware Workstation 10 虚拟操作 ... 
- 如何给oneindex网盘增加评论、密码查看、read me,头提示功能。
			来自我的博客:www.resource143.com 微信公众号:资源库resource 视频教程地址 点击查看 评论功能 特性 使用 GitHub 登录 支持多语言 [en, zh-CN, zh-T ... 
- 牛客OI周赛8-提高组A-用水填坑
			牛客OI周赛8-提高组A-用水填坑 题目 链接: https://ac.nowcoder.com/acm/contest/403/A 来源:牛客网 时间限制:C/C++ 2秒,其他语言4秒 空间限制: ... 
- 删除数据库的数据后让id从1开始算
			delete from t_AttendanceRecorddbcc checkident('t_AttendanceRecord',reseed,0) truncate table 表名称 
- maven开发项目中遇到的问题 StartChild.call at java.util.concurrent.FutureTask.run
			这个原因是没有配置 pom中没有配置 <scope>provided</scope> 导致冲突 正确的配置文件如下 <project xmlns="http: ... 
- PHP加密解密数字,适用于URL加密。
			本博主最近正在建设一个9元包邮的网站,希望各位光临指导一些意见: 9元包邮 http://www.jiubaou.com/ <?php /** * 加密解密类 * 该算法仅支持加密数字.比较适用 ... 
- 数据库其他注入思路 - 万能密码 - cookie注入 -搜索型注入
			另类登录注入形式: 经常有一类验证(ASP,PHP,JSP均存在),先判断user是否存在,ASP为例子:"select password from admin where user_nam ... 
- Java简单聊天室
			实现Java简单的聊天室 所用主要知识:多线程+网络编程 效果如下图 /** * * @author Administrator * * 简单的多人聊天系统——重点:同时性,异步性 * 1.客户端:发 ... 
