mybatis二级缓存

Mybatis中一级缓存 和 二级缓存的区别

两者区别:一级缓存的作用域是在SqlSession中,二级缓存的作用域是针对mapper做缓存。

一级缓存(本地缓存)

一级缓存是框架默认为我们开启的,我们不需要做任何配置。
例如我们首次查询id为1的用户,mybatis会将该用户的对象存储在一级缓存中;
如果在此中间 sqlSession 执行了commit操作(增删改) ,则mybatis会清空一级缓存的数据 ,这样就能让我们的数据是最新的,避免产生脏读。
当我们再次查 id 为 1 的用户时,mybatis就会去缓存中查找,就不需要再从数据库中去查询。

mybatis一级缓存是默认开启的,是SqlSession级别的缓存,在操作数据库的时候需要创建一个SqlSession,其中有一个HashMap,用于存储缓存数据。不同的SqlSession之间,其缓存数据的HashMap是不同的;

所以当我们多次调用同一个Mapper和同一个方法的同一个参数,只会进行一次数据库查询,然后把数据缓存到缓冲中,以后直接先从缓存中取出数据,不会直接去查数据库。但是不同的SqlSession对象,因为不同的SqlSession都是相互隔离的,所以相同的Mapper、参数和方法,他还是会再次发送到SQL到数据库去执行,返回结果。所以我们需要根据需求开启二级缓存

关于二级缓存

二级缓存是 mapper 映射级别的缓存,多个 SqlSession 去操作同一个 Mapper 映射的 sql 语句,多个SqlSession可以共用二级缓存,二级缓存是跨 SqlSession 的。

不管Sqlsession 是否相同,只要 mapper 的 namespace相同就能共享数据。也可以称之为 namespace 级别的缓存 。

sqlSession 关闭后(close) ,一级缓存的数据会保存到二级缓存中,新的相同的查询语句就会去二级缓存中去查询。

二级缓存是Mapper级别的缓存,多个SqlSession去操作同一个Mapper中的SQL语句,则这些SqlSession可以共享二级缓存,即二级缓存是跨SqlSession的。

二级缓存的结构图

在这里插入图片描述
sqlSession1 去查询用户信息,查询到用户信息会将查询数据存储到二级缓存中。

如果 SqlSession3 去执行相同 mapper 映射下 sql,执行 commit 提交, 将会清空该 mapper 映射下的二级缓存区域的数据。

sqlSession2 去查询与 sqlSession1 相同的用户信息, 首先会去缓存中找是否存在数据,如果存在直接从缓存中取出数据。

如何实现

在 SqlMapCong.xml 文件开启二级缓存

<settings><!全局开启二级缓存(可以省略, 因为默认就是true)><settingname="cacheEnabled"value="true"/></settings>

因为 cacheEnabled 的取值默认就为 true,所以这一步可以省略不配置。为 true 代表开启二级缓存;为 false代表不开启二级缓存。

配置相关的 Mapper 映射文件

标签表示当前这个 mapper 映射将使用二级缓存,区分的标准就看 mapper 的 namespace 值。

<mappernamespace="com.itheima.dao.UserDao"><!设置当前的映射文件对应的Mapper使用二级缓存><cache/>...</mapper>

配置 statement 上面的 useCache 属性

将 UserDao.xml 映射文件中的标签中设置 useCache="true"代表当前这个 statement 要使用二级缓存,如果不使用二级缓存可以设置为 false。

注意: 针对每次查询都需要最新的数据 sql,要设置成 useCache=false,禁用二级缓存

<select id="findByUid" parameterType="int" resultType="User" useCache="true">SELECT * FROM t_user WHERE uid = #{uid}</select>

注意事项

需要将要存储数据的 pojo 实现 Serializable接口,为了将数据取出做反序列化操作, 因为二级的缓存的存储方式多种多样,有可能存储在内存中,也可能储存到磁盘中。如果我们要再取这个缓存的话,就需要反序列化了。所以建议mybatis中的pojo都去实现Serializable接口。

总结

1、当为select语句时:
flushCache默认为false,表示任何时候语句被调用,都不会去清空本地缓存和二级缓存。
useCache默认为true,表示会将本条语句的结果进行二级缓存。

2、当为insert、update、delete语句时:
flushCache默认为true,表示任何时候语句被调用,都会导致本地缓存和二级缓存被清空。
useCache属性在该情况下没有。

当为select语句的时候,如果没有去配置flushCache、useCache,那么默认是启用缓存的,所以,如果有必要,那么就需要人工修改配置。

参考文献:
https://blog.csdn.net/weixin_45286347/article/details/124149359
https://baijiahao.baidu.com/s?id=1672974128982804783&wfr=spider&for=pc

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不能吃辣的JAVA程序猿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值