一次读懂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 同 ...
随机推荐
- CSIC_716_20191116【常用模块的用法 time ,datetime, random, os, sys, hashlib】
import time import datetime import os import sys import random import hashlib time模块 时间戳(Timestamp) ...
- css---7自定义字体
1.Adobe illustrator AI是一种应用于出版.多媒体和在线图像的工业标准矢量插画的软件,是一款非常好的矢量图形处理工具. 该软件主要应用于印刷出版.海报书籍排版.专业插画.多媒体图像处 ...
- Nacos v0.7.0:对接CMDB,实现基于标签的服务发现能力
Nacos近期发布了0.7.0版本,该版本支持对接第三方CMDB获取CMDB数据.使用Selector机制来配置服务的路由类型.支持单机模式使用MySQL数据库.上线Node.js客户端,并修复了一些 ...
- VS2010-MFC(字体和文本输出:文本输出)
转自:http://www.jizhuomi.com/software/241.html 上一节讲了CFont字体类,本节主要讲解文本输出的方法和实例. 文本输出过程 在文本输出到设备以前,我们需要确 ...
- System.Web.Mvc.IAuthorizationFilter.cs
ylbtech-System.Web.Mvc.IAuthorizationFilter.cs 1.程序集 System.Web.Mvc, Version=5.2.3.0, Culture=neutra ...
- json的dump和dumps的区别
dumps是将dict转化成str格式,loads是将str转化成dict格式. dump和load也是类似的功能,只是与文件操作结合起来了. In [1]: import json In [2]: ...
- XJOI夏令营501-511NOIP训练14——好朋友
传送门:QAQQAQ 题意:noip2011就要来了,W校的同学们不仅看重这次比赛,更看重noip2011和谁住在同一个房间.同学之间的关系好坏可以用一个亲密值表示,亲密值越大,两个同学关系越好.小A ...
- Django之跨表查询——正反向查询(ManyToManyField)
1.多对多查询:涉及到两张表以上的查询. author_obj = models.Author.objects.first() print(author_obj.name) # 查询金老板写过的书 r ...
- <爬虫>黑板爬虫闯关02
import requests from lxml import etree ''' 黑板爬虫闯关02 网址:http://www.heibanke.com/lesson/crawler_ex01/ ...
- How to use view controller containment
https://www.hackingwithswift.com/example-code/uikit/how-to-use-view-controller-containment private f ...