一次读懂mybatis中的缓存机制
缓存功能针对于查询(没听说果UPDATE,INSERT语句要缓存什么,都是直接执行的)
默认情况下,mybatis会启用一级缓存。
如果使用同一个session对象调用了相同的SELECT语句,则直接会从缓存中返回结果,而不是再查询一次数据库。
注意:session调用commit或close方法后,这个session中的一级缓存就会被清空
例如: 根据日志输出可以看出,下面代码只会发出一条sql查询语句
SqlSession sqlSession = MyBatisSqlSessionFactory.openSession();
OneToManyMapper mapper = sqlSession.getMapper(OneToManyMapper.class);
Tutor findTutorById1 = mapper.findTutorById(1);
System.out.println(findTutorById1);
Tutor findTutorById2 = mapper.findTutorById(1);
System.out.println(findTutorById2);
日志文件输出:
2019-10-16 19:15:39,870 [DEBUG] com.briup.mappers.OneToManyMapper.findTutorById - ==> Preparing: select * from tutors where tutor_id=?
2019-10-16 19:15:39,999 [DEBUG] com.briup.mappers.OneToManyMapper.findTutorById - ==> Parameters: 1(Integer)
2019-10-16 19:15:40,218 [DEBUG] com.briup.mappers.OneToManyMapper.findAddressById - ====> Preparing: select * from addresses where addr_id = ?
2019-10-16 19:15:40,218 [DEBUG] com.briup.mappers.OneToManyMapper.findAddressById - ====> Parameters: 1(Integer)
2019-10-16 19:15:40,220 [DEBUG] com.briup.mappers.OneToManyMapper.findAddressById - <==== Total: 1
2019-10-16 19:15:40,221 [DEBUG] com.briup.mappers.OneToManyMapper.findCoursesByTutor - ====> Preparing: select * from courses where tutor_id=?
2019-10-16 19:15:40,221 [DEBUG] com.briup.mappers.OneToManyMapper.findCoursesByTutor - ====> Parameters: 1(Integer)
2019-10-16 19:15:40,226 [DEBUG] com.briup.mappers.OneToManyMapper.findCoursesByTutor - <==== Total: 2
2019-10-16 19:15:40,226 [DEBUG] com.briup.mappers.OneToManyMapper.findTutorById - <== Total: 1
Tutor [tutorId=1, name=null, email=zs@briup.com, phone=PhoneNumber [countryCode=123, stateCode=456, number=7890], address=Address [addrId=1, street=redSt, city=kunshan, state=W, zip=12345, country=china], courses=[Course [courseId=1, name=JavaSE, description=JavaSE, startDate=Thu Jan 10 00:00:00 CST 2019, endDate=Sun Feb 10 00:00:00 CST 2019], Course [courseId=3, name=MyBatis, description=MyBatis, startDate=Thu Jan 10 00:00:00 CST 2019, endDate=Wed Feb 20 00:00:00 CST 2019]]]
Tutor [tutorId=1, name=null, email=zs@briup.com, phone=PhoneNumber [countryCode=123, stateCode=456, number=7890], address=Address [addrId=1, street=redSt, city=kunshan, state=W, zip=12345, country=china], courses=[Course [courseId=1, name=JavaSE, description=JavaSE, startDate=Thu Jan 10 00:00:00 CST 2019, endDate=Sun Feb 10 00:00:00 CST 2019], Course [courseId=3, name=MyBatis, description=MyBatis, startDate=Thu Jan 10 00:00:00 CST 2019, endDate=Wed Feb 20 00:00:00 CST 2019]]]
从以上日志可以分析出来,这个select语句只发了一次,第二次的查询用的是第一次查询的缓存
二级缓存: 在不同的session对象之间可以共享缓存的数据
1.mybatis-config.xml文件中保证<setting name="cacheEnabled" value="true"/>设置中是缓存功能是开启的,默认就是开启的true
2.在需要二级缓存的xml映射文件中,手动开启缓存功能,在根元素中加入一个标签即可:<cache/>
3.一个session查询完数据之后,需要调用commit或者close方法后,这个数据才会进入到二级缓存中,然后其他session就可以共享到这个缓存数据了
注意:默认情况下,被二级缓存保存的对象需要实现序列化接口。
例如:
mybatis-config.xml:
<settings>
<setting name="cacheEnabled" value="true"/>
</settings>
xml映射文件:
<mapper namespace="com.briup.mappers.SpecialMapper">
<cache/>
<select> ..</select>
<select> ..</select>
<select> ..</select>
</mapper>
测试代码:
@Test
public void test_cache2(){
SqlSession session1 = null;
SqlSession session2 = null;
try {
session1 = MyBatisSqlSessionFactory.openSession();
session2 = MyBatisSqlSessionFactory.openSession(); SpecialMapper mapper1 = session1.getMapper(SpecialMapper.class);
SpecialMapper mapper2 = session2.getMapper(SpecialMapper.class); User user1 = mapper1.findUserById(56);
System.out.println(user1);
session1.commit(); User user2 = mapper2.findUserById(56);
System.out.println(user2);
session2.commit();
} catch (Exception e) {
e.printStackTrace();
}finally {
if(session1!=null)session1.close();
if(session2!=null)session2.close();
}
}
日志文件输出:
2019-10-16 19:29:22,443 [DEBUG] com.briup.mappers.OneToManyMapper - Cache Hit Ratio [com.briup.mappers.OneToManyMapper]: 0.0
2019-10-16 19:29:23,449 [DEBUG] com.briup.mappers.OneToManyMapper.findTutorById - ==> Preparing: select * from tutors where tutor_id=?
2019-10-16 19:29:23,648 [DEBUG] com.briup.mappers.OneToManyMapper.findTutorById - ==> Parameters: 1(Integer)
2019-10-16 19:29:23,805 [DEBUG] com.briup.mappers.OneToManyMapper - Cache Hit Ratio [com.briup.mappers.OneToManyMapper]: 0.0
2019-10-16 19:29:23,805 [DEBUG] com.briup.mappers.OneToManyMapper.findAddressById - ====> Preparing: select * from addresses where addr_id = ?
2019-10-16 19:29:23,806 [DEBUG] com.briup.mappers.OneToManyMapper.findAddressById - ====> Parameters: 1(Integer)
2019-10-16 19:29:23,808 [DEBUG] com.briup.mappers.OneToManyMapper.findAddressById - <==== Total: 1
2019-10-16 19:29:23,808 [DEBUG] com.briup.mappers.OneToManyMapper - Cache Hit Ratio [com.briup.mappers.OneToManyMapper]: 0.0
2019-10-16 19:29:23,809 [DEBUG] com.briup.mappers.OneToManyMapper.findCoursesByTutor - ====> Preparing: select * from courses where tutor_id=?
2019-10-16 19:29:23,809 [DEBUG] com.briup.mappers.OneToManyMapper.findCoursesByTutor - ====> Parameters: 1(Integer)
2019-10-16 19:29:23,814 [DEBUG] com.briup.mappers.OneToManyMapper.findCoursesByTutor - <==== Total: 2
2019-10-16 19:29:23,814 [DEBUG] com.briup.mappers.OneToManyMapper.findTutorById - <== Total: 1
Tutor [tutorId=1, name=null, email=zs@briup.com, phone=PhoneNumber [countryCode=123, stateCode=456, number=7890], address=Address [addrId=1, street=redSt, city=kunshan, state=W, zip=12345, country=china], courses=[Course [courseId=1, name=JavaSE, description=JavaSE, startDate=Thu Jan 10 00:00:00 CST 2019, endDate=Sun Feb 10 00:00:00 CST 2019], Course [courseId=3, name=MyBatis, description=MyBatis, startDate=Thu Jan 10 00:00:00 CST 2019, endDate=Wed Feb 20 00:00:00 CST 2019]]]
2019-10-16 19:29:23,825 [DEBUG] com.briup.mappers.OneToManyMapper - Cache Hit Ratio [com.briup.mappers.OneToManyMapper]: 0.25
Tutor [tutorId=1, name=null, email=zs@briup.com, phone=PhoneNumber [countryCode=123, stateCode=456, number=7890], address=Address [addrId=1, street=redSt, city=kunshan, state=W, zip=12345, country=china], courses=[Course [courseId=1, name=JavaSE, description=JavaSE, startDate=Thu Jan 10 00:00:00 CST 2019, endDate=Sun Feb 10 00:00:00 CST 2019], Course [courseId=3, name=MyBatis, description=MyBatis, startDate=Thu Jan 10 00:00:00 CST 2019, endDate=Wed Feb 20 00:00:00 CST 2019]]]
可以看出,sqlSession2这个对象第二次查询的时候,命中了缓存
2019-10-16 19:29:23,825 [DEBUG] com.briup.mappers.OneToManyMapper - Cache Hit Ratio [com.briup.mappers.OneToManyMapper]: 0.25(缓存命中率0.25)
二级缓存补充说明
1. 映射语句文件中的所有select语句将会被缓存
2. 映射语句文件中的所有insert,update和delete语句会刷新缓存
3. 缓存会使用Least Recently Used(LRU,最近最少使用的)算法来收回。
4. 缓存会根据指定的时间间隔来刷新。
5. 缓存会存储1024个对象
cache标签常用属性:
<cache
eviction="FIFO" <!--回收策略为先进先出-->
flushInterval="60000" <!--自动刷新时间60s-->
size="512" <!--最多缓存512个引用对象-->
readOnly="true"/> <!--true表示对象不能被写出去,即不可以被序列化,false表示可以写出去,即可以被序列化,默认值是false-->
一次读懂mybatis中的缓存机制的更多相关文章
- SSM-MyBatis-17:Mybatis中一级缓存(主要是一级缓存存在性的证明,增删改对一级缓存会造成什么影响)
------------吾亦无他,唯手熟尔,谦卑若愚,好学若饥------------- 缓存------------------------------------------> 很熟悉的一个 ...
- [原创]关于mybatis中一级缓存和二级缓存的简单介绍
关于mybatis中一级缓存和二级缓存的简单介绍 mybatis的一级缓存: MyBatis会在表示会话的SqlSession对象中建立一个简单的缓存,将每次查询到的结果结果缓存起来,当下次查询的时候 ...
- 一步步教你读懂NET中IL(附带图)
一步步教你读懂NET中IL(附带图) 接触NET也有1年左右的时间了,NET的内部实现对我产生了很大的吸引力,在msdn上找到一篇关于NET的IL代码的图解说明,写的挺不错的.个人觉得:能对这些底部的 ...
- mybatis中的缓存问题
关于mybatis基础我们前面几篇博客已经介绍了很多了,今天我们来说一个简单的问题,那就是mybatis中的缓存问题.mybatis本身对缓存提供了支持,但是如果我们没有进行任何配置,那么默认情况下系 ...
- 关于mybatis中一级缓存和二级缓存的简单介绍
关于mybatis中一级缓存和二级缓存的简单介绍 mybatis的一级缓存: MyBatis会在表示会话的SqlSession对象中建立一个简单的缓存,将每次查询到的结果结果缓存起来,当下次查询的时候 ...
- Mybatis中的缓存管理
目录 Mybatis中的缓存管理 查询缓存工作原理: 配置缓存: 默认配置: 使用二级缓存: 刷新缓存过程: 配置EHcache 产生脏数据 使用原则: Mybatis中的缓存管理 查询缓存工作原理: ...
- 【面试普通人VS高手系列】说一说Mybatis里面的缓存机制
一个工作了 5年的程序员,在私信里面不断向我诉苦. 他说,他用了Mybatis这么久,怎么滴也算是精通Mybatis了吧. 结果竟然在Mybatis这个面试题上翻车了! 真的好烦! 好吧,我们今天来看 ...
- SSM-MyBatis-18:Mybatis中二级缓存和第三方Ehcache配置
------------吾亦无他,唯手熟尔,谦卑若愚,好学若饥------------- 二级缓存 Mybatis中,默认二级缓存是开启的.可以关闭. 一级缓存开启的.可以被卸载吗?不可以的.一级缓存 ...
- MyBatis中的缓存1
1.应用程序和数据库交互的过程是一个相对比较耗时的过程 2.缓存存在的意义:让应用程序减少对数据库的访问,提升程序运行的xiaolv 3.MyBatis中默认SqlSession缓存开启 3.1 同 ...
随机推荐
- 2018-8-10-win10-uwp-在-Canvas-放一个超过大小的元素会不会被裁剪
title author date CreateTime categories win10 uwp 在 Canvas 放一个超过大小的元素会不会被裁剪 lindexi 2018-08-10 19:16 ...
- scala入门基础学习
1.Scala基础语法 区分大小写 类名 - 对于所有的类名的第一个字母要大写.如果需要使用几个单词来构成一个类的名称,每个单词的第一个字母要大写. 方法名称 - 所有的方法名称的第一个字母用小写. ...
- Android欢迎页短暂白屏
在style中application theme下添加以下代码: <item name="android:windowIsTranslucent" >true</ ...
- Android开发 ImageView开发记录
改变图片的着色 默认是这个方法 /** * 为图像设置着色选项. Assumes * {@link PorterDuff.Mode#SRC_ATOP} blending mode. * * @para ...
- MySQL高可用(Galera Cluster)
Galera Cluster简介 Galera Cluster是集成了Galera插件的MySQL集群,是一种新型的,数据不共享的,高度冗余的高可用方案,目前Galera Cluster有两个版本,分 ...
- Kubernetes的包管理工具Helm的安装和使用
1.源码安装 [root@master ~]# wget https://storage.googleapis.com/kubernetes-helm/helm-v2.14.0-linux-amd64 ...
- Delphi利用Windows GDI实现文字倾斜
Delphi利用Windows GDI实现文字倾斜 摘要 Delphi利用Windows GDI实现文字倾斜 procedure TForm1.FormPaint(Sender: TObject);v ...
- json的dump和dumps的区别
dumps是将dict转化成str格式,loads是将str转化成dict格式. dump和load也是类似的功能,只是与文件操作结合起来了. In [1]: import json In [2]: ...
- zookeeper 选举白话理解
- 学SpringBoot一篇就够了
1.SpringBoot概述 Spring 框架对于很多 Java 开发人员来说都不陌生.自从 2002 年发布以来,Spring 框架已经成为企业应用开发领域非常流行的基础框架.有大量的企业应用基于 ...