一次读懂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 同 ...
随机推荐
- StringBuilder 和 StringBuffer类
通常在涉及到StringBuilder和StringBuffer时中任何一个时,都应该想到另外一个并且在脑海中问自己是否用另外一个更加合适. 为什么这么说,请继续往下看,当然如果你已经对二者烂熟于胸自 ...
- Python 执行tail文件并操作
def log_search(self, logfile, search_content, timeout=10): import time import subprocess import sele ...
- launch-s.sh 发布脚本备份
[root@izm5ef2ow9zssfxi6opoucz code]# cat launch-s.sh serverId=1313 zipName=$1 serverPath='code-s'$se ...
- css---5 only-child or nth-of-type
1 _nth-child系列 :nth-child(index) <!DOCTYPE html> <html lang="en"> <head> ...
- xampp只允许本地访问,禁止远程访问
远程访问phpmyadmin的时候出现错误 New XAMPP security concept: Access to the requested object is only available f ...
- 【JZOJ6277】矩阵游戏
description analysis 设所有操作之后,\(f[i]\)表示\(i\)行乘的数,\(g[j]\)表示\(j\)列乘的数,那么 \[Answer=\sum^{n}_{i=1}\sum^ ...
- PHP正则使用技巧1
$pattern="/<div class=\"cover g-playicon\">(.*?)>/s"; 意思为抓取<div clas ...
- PSCC2019常用基础操作
一.常用设置 1.界面设置(快捷键Ctrl+K):可以对PS界面的颜色.导出格式.性能等等进行设置(这里暂存盘建议设置D盘或F盘,默认C盘). 2.常用面板整理(菜单栏->窗口) 二.常用快捷键 ...
- django2 rest_framework + vue.js + mysql5.6 实现增删改查
1.安装pymysql,mysqlclient,创建项目django-admin startproject django3 2.在Mysql中创建一个数据库叫django3db,打开项目,修改一下数据 ...
- js 仿微信投诉—引入vue.js,拆分组件为单个js
效果 页面目录 index.html <!DOCTYPE html > <html> <head> <meta charset="UTF-8&quo ...