Mybatis的缓存
1.缓存是什么
在 Mybatis 里面,所谓的缓存就是将已经查询过的记录放在内存的缓冲区或文件上,这样如果再次查询,可以通过配置的策略,命中已经查询过的记录,从而提高查询的效率。
Mybatis 的缓存分为一级缓存和二级缓存。
2.一级缓存
一级缓存:所谓的一级缓存就是会话级别的缓存,就是同一个会话,如果已经查询过的数据会保存一份在内存中,如果会话没有关闭,再次调用同样的方法查询,不会再查询数据库,,而是直接从缓存中取出之前查询的数据.。一级缓存默认是打开的,而且是关闭不了的。一下代码,调用了 5 次 findAll 方法,但执行只查询了一次数据库。说明默认一级缓存是打开的。
@Test
public void findAll(){
try {
//1.获得操作对象
SqlSession session = DbUtils.getSession();
//2.使用 session.获得映射接口的代理对象,这个代理对象是 mybatis 通过StudentMapper.xml 创建的
StudentMapper studentMapper = session.getMapper(StudentMapper.class);
List<Student> list = studentMapper.findAll();
List<Student> list1 = studentMapper.findAll();
List<Student> list2 = studentMapper.findAll();
List<Student> list3 = studentMapper.findAll();
List<Student> list4 = studentMapper.findAll();
for(Student s:list4){
System.out.print("姓名:"+s.getSname());
System.out.print(",年龄:"+s.getAge());
System.out.println(",生日:"+s.getBirthday());
}
session.commit();
session.close();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
查看代码
--重点查看控制台输出了多少条 SQL,来分析一级缓存是存在。
结论:调用了五次方法,查询了五次相同数据。但后台输出的是一条 SQL 语句,说明默
认就支持一级缓存的。

2.1如何清空一级缓存
1.关闭会话.close()
2.进行了操作(增删改),提交了 commit();
3.手工清除缓存 clearCache() 一下代码,手工清除了一次缓存,操作数据一次,所以会查询三次数据库
@Test
public void findAll(){
try {
SqlSession session = DbUtils.getSession();
StudentMapper studentMapper =
session.getMapper(StudentMapper.class);
List<Student> list = studentMapper.findAll();
//清除一级缓存
session.clearCache();
List<Student> list1 = studentMapper.findAll();
//操作数据库,一级缓存会清除
studentMapper.deleteByIds(3);
List<Student> list2 = studentMapper.findAll();
List<Student> list3 = studentMapper.findAll();
List<Student> list4 = studentMapper.findAll();
for(Student s:list4){
System.out.print("姓名:"+s.getSname());
System.out.print(",年龄:"+s.getAge());
System.out.println(",生日:"+s.getBirthday());
}
session.commit();
session.close();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
查看代码

3.二级缓存
所谓二级缓存其实就是文件级别的缓存。 有效范围就是同一个映射文件,即使关闭会话都不会清空的缓存!
内置二级缓存的配置
1.在映射文件增加一个二级缓存的配置

2.二级缓存需要将Java 的对象序列化到本地。实体类要增加一个序列化接口Serializable所谓的序列化(串行化),就是将对象变成一个流格式。这样对象就可以完成保存到本地或者网络传递!
public class Student implements Serializable {
private Integer sid;
private Integer aid;
private String sname;
private String sex;
private Date birthday;
private Integer age;
public String getSname() {
return sname;
}
public void setSname(String sname) {
this.sname = sname;
}
public Integer getSid() {
return sid;
}
public void setSid(Integer sid) {
this.sid = sid;
}
public Integer getAid() {
return aid;
}
public void setAid(Integer aid) {
this.aid = aid;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
查看代码
3.新版本已经默认支持开启二级缓存.可以不改
<settings>
<!-- 默认支持骆驼命名法 -->
<setting name="mapUnderscoreToCamelCase" value="true"/>
<!-- 启动缓存,新版本已经默认支持了,可以不配置 -->
<setting name="cacheEnabled" value="true"/>
</settings>
查看代码
结果:内置的二级缓存发现缓存的命中率很低,基本不起作用


那么如何解决这个缺陷?
使用第三方的缓存 ehcache,而ehcache 需要 slf4j 这个日志包支持
3.1ehcache 的整合配置
1.导入包

2.配置第三方缓存
<cache type="org.mybatis.caches.ehcache.EhcacheCache" >
<!--最大的空闲时间 -->
<property name="timeToIdleSeconds" value="10000"/>
<!-- 最大的在线时间 -->
<property name="timeToLiveSeconds" value="20000"/>
<!-- 内存的大小 b 字节 m1 =1024k 1k=1024b -->
<property name="maxEntriesLocalHeap" value="2000000"/>
<!-- 文件的大小 b 字节-->
<property name="maxEntriesLocalDisk" value="20000000"/>
<!-- 算法 LRU:最少使用优先, "LFU" or "FIFO:先进先出 -->
<property name="memoryStoreEvictionPolicy" value="LRU"/>
</cache>
查看代码
结果:命中率 100%

什么是命中率,就是已经查询的数据,在找到的几率。使用同样的方法时,可以匹配原来的数据的概率;就是第二次以后的查询,找回第一查询的数据的概率,数据少的时候基本都是 100%。
Mybatis的缓存的更多相关文章
- 通过源码分析MyBatis的缓存
前方高能! 本文内容有点多,通过实际测试例子+源码分析的方式解剖MyBatis缓存的概念,对这方面有兴趣的小伙伴请继续看下去~ MyBatis缓存介绍 首先看一段wiki上关于MyBatis缓存的介绍 ...
- MyBatis 一级缓存与二级缓存
MyBatis一级缓存 MyBatis一级缓存默认开启,一级缓存为Session级别的缓存,在执行以下操作时一级缓存会清空 1.执行session.clearCache(); 2.执行CUD操作 3. ...
- Mybatis学习记录(七)----Mybatis查询缓存
1. 什么是查询缓存 mybatis提供查询缓存,用于减轻数据压力,提高数据库性能. mybaits提供一级缓存,和二级缓存. 一级缓存是SqlSession级别的缓存.在操作数据库时需要构造 sql ...
- 八 mybatis查询缓存(一级缓存,二级缓存)和ehcache整合
1 查询缓存 1.1 什么是查询缓存 mybatis提供查询缓存,用于减轻数据压力,提高数据库性能. mybaits提供一级缓存,和二级缓存.
- MyBatis一级缓存引起的无穷递归
MyBatis一级缓存引起的无穷递归 引言: 最近在项目中参与了一个领取优惠劵的活动,当多个用户领取同一张优惠劵的时候,使用了数据库锁控制并发,起初的设想是:如果多个人同时领一张劵,第一个到达的人领取 ...
- Spring+SpringMVC+MyBatis深入学习及搭建(八)——MyBatis查询缓存
转载请注明出处:http://www.cnblogs.com/Joanna-Yan/p/6956206.html 前面讲到:Spring+SpringMVC+MyBatis深入学习及搭建(七)——My ...
- 【MyBatis源码解析】MyBatis一二级缓存
MyBatis缓存 我们知道,频繁的数据库操作是非常耗费性能的(主要是因为对于DB而言,数据是持久化在磁盘中的,因此查询操作需要通过IO,IO操作速度相比内存操作速度慢了好几个量级),尤其是对于一些相 ...
- mybatis一级缓存二级缓存
一级缓存 Mybatis对缓存提供支持,但是在没有配置的默认情况下,它只开启一级缓存,一级缓存只是相对于同一个SqlSession而言.所以在参数和SQL完全一样的情况下,我们使用同一个SqlSess ...
- 深入浅出mybatis之缓存机制
目录 前言 准备工作 MyBatis默认缓存设置 缓存实现原理分析 参数localCacheScope控制的缓存策略 参数cacheEnabled控制的缓存策略 总结 前言 提到缓存,我们都会不约而同 ...
随机推荐
- pyhton崩溃的第六天,又有新成员
首先在今天的刚刚开始,补充一下上次两个成员的一些特有的方法,一个是列表,一个是字典,首先列表里面多了一个反转的方法,名叫reverse,简单就是把列表中的123变成了321,还有一个方法是sort,是 ...
- Rabbitmq集群高可用
转载:https://www.cnblogs.com/flat_peach/archive/2013/04/07/3004008.html RabbitMQ是用erlang开发的,集群非常方便,因为e ...
- SQL 行转列的运用
适用场景:需要将行数据转换成列数据 例子: 现在有一个学生的成绩表 但是我们需要将每个学生的成绩汇集到一条数据上,这时候就可以用到行转列. 代码如下 一.不使用 PIVOT SELECT ),[St ...
- WinForms 快速开发的工具类。
下面是我本人在 WinForms 开发中积累的一些心得. 1. 在父窗体中打开子窗体 直接贴代码: private void btnCompare_Click(object sender, Event ...
- from语法导入
"""# 在执行文件中能不能直接使用模块中的名字 # import m1# import m1 as m# print(m1.a)# print(m1.b)# print ...
- [解读REST] 2.REST用来干什么的?
衔接上文[解读REST] 1.REST的起源,介绍了REST的诞生背景.每当笔者遇到一个新事物的想去了解的时候,总是会问上自己第一个问题,这个新事物是干什么用的?在解释我所理解的REST这个过程中也不 ...
- 在Winform开发框架中对附件文件进行集中归档处理
在我们Winform开发中,往往需要涉及到附件的统一管理,因此我倾向于把它们独立出来作为一个附件管理模块,这样各个模块都可以使用这个附件管理模块,更好的实现模块重用的目的.在涉及附件管理的场景中,一个 ...
- jeecg入门操作—模板配置(录入界面)
点击online表单的模板配置,进入模板设计列表页面,点击创建模板 点击创建模板 点击激活 设计完成,点击激活(表单模板可以多个,激活状态只能有一个) 激活后,重新加入功能测试,点击添加页面,效果如下 ...
- jeecg入门操作—字典配置
一.字典入口 系统 管理->数据字典 二.录入字典 填写字典相关信息 三 .添加字典内容 填写字典某条记录内容 再录入几条 录入之后的字典内容 四.使用字典 1.编辑用户表单,添加用户等级字段 ...
- Django子应用里的通用类混合视图处理
# 子应用的views.py此文件用于编写Web应用视图,处理复杂的业务逻辑 #导入方法视图模板 from django.shortcuts import render #导包 from django ...