前言

先说缓存,合理使用缓存是优化中最常见的,将从数据库中查询出来的数据放入缓存中,下次使用时不必从数据库查询,而是直接从缓存中读取,避免频繁操作数据库,减轻数据库的压力,同时提高系统性能。
一级缓存
一级缓存是SqlSession级别的缓存。在操作数据库时需要构造sqlSession对象,在对象中有一个数据结构用于存储缓存数据。不同的sqlSession之间的缓存数据区域是互相不影响的。也就是他只能作用在同一个sqlSession中,不同的sqlSession中的缓存是互相不能读取的。
一级缓存的工作原理:
用户发起查询请求,查找某条数据,sqlSession先去缓存中查找,是否有该数据,如果有,读取;
如果没有,从数据库中查询,并将查询到的数据放入一级缓存区域,供下次查找使用。
但sqlSession执行commit,即增删改操作时会清空缓存。这么做的目的是避免脏读。
如果commit不清空缓存,会有以下场景:A查询了某商品库存为10件,并将10件库存的数据存入缓存中,之后被客户买走了10件,数据被delete了,但是下次查询这件商品时,并不从数据库中查询,而是从缓存中查询,就会出现错误。
既然有了一级缓存,那么为什么要提供二级缓存呢?
二级缓存是mapper级别的缓存,多个SqlSession去操作同一个Mapper的sql语句,多个SqlSession可以共用二级缓存,二级缓存是跨SqlSession的。二级缓存的作用范围更大。
还有一个原因,实际开发中,MyBatis通常和Spring进行整合开发。Spring将事务放到Service中管理,对于每一个service中的sqlsession是不同的,这是通过mybatis-spring中的org.mybatis.spring.mapper.MapperScannerConfigurer创建sqlsession自动注入到service中的。
每次查询之后都要进行关闭sqlSession,关闭之后数据被清空。所以spring整合之后,如果没有事务,一级缓存是没有意义的。
二级缓存
二级缓存原理:
二级缓存是mapper级别的缓存,多个SqlSession去操作同一个Mapper的sql语句,多个SqlSession可以共用二级缓存,二级缓存是跨SqlSession的。
UserMapper有一个二级缓存区域(按namespace分),其它mapper也有自己的二级缓存区域(按namespace分)。每一个namespace的mapper都有一个二级缓存区域,两个mapper的namespace如果相同,这两个mapper执行sql查询到数据将存在相同的二级缓存区域中。
开启二级缓存:
1,打开总开关
在MyBatis的配置文件中加入:
<span style="font-size:18px;"><settings> <!--开启二级缓存--> <setting name="cacheEnabled" value="true"/> </settings> </span>
2,在需要开启二级缓存的mapper.xml中加入caceh标签
<span style="font-size:18px;"><cache/></span>
3,让使用二级缓存的POJO类实现Serializable接口
<span style="font-size:18px;">public class User implements Serializable {}</span>
测试一下
<span style="font-size:18px;">@Test
public void testCache2() throws Exception {
SqlSession sqlSession1 = sqlSessionFactory.openSession();
SqlSession sqlSession2 = sqlSessionFactory.openSession();
UserMapper userMapper1 = sqlSession1.getMapper(UserMapper.class);
User user1 = userMapper1.findUserById(1);
System.out.println(user1);
sqlSession1.close();
UserMapper userMapper2 = sqlSession2.getMapper(UserMapper.class);
User user2 = userMapper2.findUserById(1);
System.out.println(user2);
sqlSession2.close();
}</span>
输出结果:
<span style="font-size:18px;">DEBUG [main] - Cache Hit Ratio [com.iot.mybatis.mapper.UserMapper]: 0.0 DEBUG [main] - Opening JDBC Connection DEBUG [main] - Created connection 103887628. DEBUG [main] - Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@631330c] DEBUG [main] - ==> Preparing: SELECT * FROM user WHERE id=? DEBUG [main] - ==> Parameters: 1(Integer) DEBUG [main] - <== Total: 1 User [id=1, username=张三, sex=1, birthday=null, address=null] DEBUG [main] - Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@631330c] DEBUG [main] - Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@631330c] DEBUG [main] - Returned connection 103887628 to pool. DEBUG [main] - Cache Hit Ratio [com.iot.mybatis.mapper.UserMapper]: 0.5 User [id=1, username=张三, sex=1, birthday=null, address=null]</span>
我们可以从打印的信息看出,两个sqlSession,去查询同一条数据,只发起一次select查询语句,第二次直接从Cache中读取。
前面我们说到,Spring和MyBatis整合时, 每次查询之后都要进行关闭sqlSession,关闭之后数据被清空。所以spring整合之后,如果没有事务,一级缓存是没有意义的。那么如果开启二级缓存,关闭sqlsession后,会把该sqlsession一级缓存中的数据添加到namespace的二级缓存中。这样,缓存在sqlsession关闭之后依然存在。
总结:
对于查询多commit少且用户对查询结果实时性要求不高,此时采用mybatis二级缓存技术降低数据库访问量,提高访问速度。
但不能滥用二级缓存,二级缓存也有很多弊端,从MyBatis默认二级缓存是关闭的就可以看出来。
二级缓存是建立在同一个namespace下的,如果对表的操作查询可能有多个namespace,那么得到的数据就是错误的。
举个简单的例子:
订单和订单详情,orderMapper、orderDetailMapper。在查询订单详情时我们需要把订单信息也查询出来,那么这个订单详情的信息被二级缓存在orderDetailMapper的namespace中,这个时候有人要修改订单的基本信息,那就是在orderMapper的namespace下修改,他是不会影响到orderDetailMapper的缓存的,那么你再次查找订单详情时,拿到的是缓存的数据,这个数据其实已经是过时的。
根据以上,想要使用二级缓存时需要想好两个问题:
1)对该表的操作与查询都在同一个namespace下,其他的namespace如果有操作,就会发生数据的脏读。
2)对关联表的查询,关联的所有表的操作都必须在同一个namespace。
好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对的支持。
# mybatis的缓存处理
# mybatis二级缓存配置
# mybatis
# 二级缓存
# 深入理解Mybatis二级缓存
# MyBatis关于二级缓存问题
# 详解Mybatis的二级缓存配置
# mybatis二级缓存的实现代码
# Mybatis如何通过注解开启使用二级缓存
# MyBatis中一级缓存和二级缓存的区别
# 在分布式环境下正确使用MyBatis二级缓存的最佳实践
# 多个
# 清空
# 如果没有
# 数据库中
# 就会
# 也有
# 都要
# 并将
# 下次
# 在同一个
# 有一个
# 自己的
# 时需
# 的是
# 这是
# 是在
# 都有
# 会有
# 好了
# 是他
相关文章:
Dapper的Execute方法的返回值是什么意思 Dapper Execute返回值详解
定制建站哪家更专业可靠?推荐榜单揭晓
如何在Tomcat中配置并部署网站项目?
杭州银行网站设计制作流程,杭州银行怎么开通认证方式?
定制建站方案优化指南:企业官网开发与建站费用解析
如何通过wdcp面板快速创建网站?
手机网站制作平台,手机靓号代理商怎么制作属于自己的手机靓号网站?
如何获取PHP WAP自助建站系统源码?
如何用景安虚拟主机手机版绑定域名建站?
油猴 教程,油猴搜脚本为什么会网页无法显示?
b2c电商网站制作流程,b2c水平综合的电商平台?
教学网站制作软件,学习*后期制作的网站有哪些?
建站之星北京办公室:智能建站系统与小程序生成方案解析
如何用腾讯建站主机快速创建免费网站?
大连网站制作费用,大连新青年网站,五年四班里的视频怎样下载啊?
武清网站制作公司,天津武清个人营业执照注销查询系统网站?
如何在橙子建站中快速调整背景颜色?
如何用5美元大硬盘VPS安全高效搭建个人网站?
php能控制zigbee模块吗_php通过串口与cc2530 zigbee通信【介绍】
企业在线网站设计制作流程,想建设一个属于自己的企业网站,该如何去做?
招商网站制作流程,网站招商广告语?
建站之星免费模板:自助建站系统与智能响应式一键生成
,制作一个手机app网站要多少钱?
再谈Python中的字符串与字符编码(推荐)
如何在腾讯云服务器快速搭建个人网站?
成都品牌网站制作公司,成都营业执照年报网上怎么办理?
如何快速搭建高效服务器建站系统?
免费制作统计图的网站有哪些,如何看待现如今年轻人买房难的情况?
rsync同步时出现rsync: failed to set times on “xxxx”: Operation not permitted
如何通过老薛主机一键快速建站?
学校免费自助建站系统:智能生成+拖拽设计+多端适配
安徽网站建设与外贸建站服务专业定制方案
如何在Golang中实现微服务服务拆分_Golang微服务拆分与接口管理方法
如何在万网自助建站中设置域名及备案?
建站之星×万网:智能建站系统+自助建站平台一键生成
如何快速建站并高效导出源代码?
建站之星与建站宝盒如何选择最佳方案?
零服务器AI建站解决方案:快速部署与云端平台低成本实践
深圳网站制作的公司有哪些,dido官方网站?
建站之星安装步骤有哪些常见问题?
定制建站模板如何实现SEO优化与智能系统配置?18字教程
制作充值网站的软件,做人力招聘为什么要自己交端口钱?
如何通过西部数码建站助手快速创建专业网站?
如何确认建站备案号应放置的具体位置?
制作网站的公司有哪些,做一个公司网站要多少钱?
如何高效配置香港服务器实现快速建站?
SQL查询语句优化的实用方法总结
建站主机助手选型指南:2025年热门推荐与高效部署技巧
建站之星好吗?新手能否轻松上手建站?
如何用IIS7快速搭建并优化网站站点?
*请认真填写需求信息,我们会在24小时内与您取得联系。