南昌网站制作方案定制,长沙有哪些网络平台公司,公司英文网站,防网站黑客前言
相信很多人都用过mybatis#xff0c;这篇文章主要是介绍mybatis的缓存#xff0c;了解一下mybatis缓存是如何实现#xff0c;以及它在实际中的应用
一级缓存
什么是mybatis一级缓存#xff1f;我们先看一个例子#xff1a;
GetMapping(/list)
public…前言
相信很多人都用过mybatis这篇文章主要是介绍mybatis的缓存了解一下mybatis缓存是如何实现以及它在实际中的应用
一级缓存
什么是mybatis一级缓存我们先看一个例子
GetMapping(/list)
public ResultVoid listGoods(){GoodsExample goodsExample new GoodsExample();goodsMapper.selectByExample(goodsExample);goodsMapper.selectByExample(goodsExample);return Result.okWithNullData();
}上面这个例子有两个相同的查询方法我们看看日志 我们看到即使两个查询方法一样它也查询了两次数据库。mybatis为了优化这种情况既然两次查询语句一样那么就将第一次结果缓存起来那么第二次查询就不用再查数据库。
其实要实现这个功能也是挺简单的你只需在方法上加上Transactional即可
Transactional
public ResultVoid listGoods(){// 代码省略
}再看看运行日志 我们可以看到只有一次查询正常情况下每发起一次查询就会创建一个SqlSession查询结束了SqlSession就会被销毁。如果开启了事务那么就可以为多个查询创建一个共同的SqlSession那么在同一个事务中如果说存在相同的查询那么后面的查询都会直接拿第一次查询的结果。
这么看来mybatis的一级缓存还不错但现实告诉你如果你的项目比较大比较复杂比如分布式如果使用mybatis的一级缓存很容易就踩坑了因此一些大公司都会要求禁用它而使用redis
mybatis是默认开启一级缓存的如果要关闭可以在配置文件这样配置
# 默认值是session如果要关闭设置成statement即可
mybatis.configuration.local-cache-scopestatement为什么说很容易踩坑呢
其实简单来说就是第一次缓存的结果被另外的线程更新了那么如果后面再拿到的数据就是脏数据。
总之禁用它使用redis代替它准没错
二级缓存
假如说现在有100个请求在同一时间请求列表数据就上面那段代码而言正常情况下要查询200次数据库
GetMapping(/list)
public ResultVoid listGoods(){GoodsExample goodsExample new GoodsExample();// 第一次查询goodsMapper.selectByExample(goodsExample);// 第二次查询goodsMapper.selectByExample(goodsExample);return Result.okWithNullData();
}如果开启了一级缓存那么也要查询100次因此mybatis就提供了二级缓存
二级缓存的设置也很简单只需在Mapper.xml文件中加上cache标签即可
?xml version1.0 encodingUTF-8?
!DOCTYPE mapper PUBLIC -//mybatis.org//DTD Mapper 3.0//EN http://mybatis.org/dtd/mybatis-3-mapper.dtd
mapper namespacecom.example.demo.dao.mapper.GoodsMapper!--缓存标签--cache/cacheresultMap idBaseResultMap typecom.example.demo.domain.entity.Goodsid columnid jdbcTypeBIGINT propertyid /result columngoods_name jdbcTypeVARCHAR propertygoodsName /result columnnumber jdbcTypeINTEGER propertynumber /result columncreate_time jdbcTypeTIMESTAMP propertycreateTime /result columnupdate_time jdbcTypeTIMESTAMP propertyupdateTime //resultMap!--省略代码--
当我们再次请求list接口时看看控制台的日志 我们可以看到除了第一次查询要查询数据库外后面的几次查询列表都是直接从缓存中拿数据
mybtais二级缓存看上去好像挺好用的但现实当中还是给你来个暴击最好不要用。
我们要搞清楚它的作用范围它时针对命名空间的就比如说上面提到的mapper.xml如果说你部署在一个节点那么就只有一个mapper.xml缓存的结果直接从这个空间下获取即可但很多时候随着业务的增大可能要部署多个节点那每个节点都有自己的mapper.xml而每个节点更新缓存只会更新自己节点的mapper.xml因此可能会出现下面的问题
客户端有个请求过来从A节点获取列表数据的如果有缓存查缓存没有就查数据库比如说meta 60产品数据它的价格时6000元
客户端再发个请求过来从B节点获取列表数据的如果有缓存查缓存没有就查数据库比如说meta 60产品数据它的价格时6000元
这是没有问题的但现在管理人员调整了产品价格从6000改成5000他的这次更新请求刚好请求了B节点(客户端请求节点是随机的)此时B节点缓存刷新了
那现在是不是会出现这样的情况有些用户看到的商品价格是6000(刚好访问了A节点直接读取缓存)有些用户看到的价格却是5000(请求了B节点B节点会重新查库)
所以mybtais二级缓存慎用