美文网首页
mybatis一级缓存和二级缓存

mybatis一级缓存和二级缓存

作者: 代码之尖 | 来源:发表于2018-12-28 17:49 被阅读0次

    MyBatis提供了支持一级缓存和二级缓存。

    一级缓存:基于PerpetualCache 的 HashMap本地缓存,其存储作用域是Session,当session flush或者close时,该session中的cache全部清空。

    二级缓存:与一级缓存机制类似,也是使用的PerpetualCache的HashMap实现,其作用域是mapper.xml(namespace),可自定义存储源,比如Encache。

    更新机制:只要在作用域内进行了增删改操作后,该作用域所有的select的cache全部clear。


    mybatis二级缓存实现

    MyBatis 包含一个非常强大的查询缓存特性,它可以非常方便地配置和定制。MyBatis 3 中的缓存实现的很多改进都已经实现了,使得它更加强大而且易于配置。

    默认情况下是没有开启缓存的,除了局部的 session 缓存,可以增强变现而且处理循环 依赖也是必须的。要开启二级缓存,你需要在你的 SQL 映射文件中添加一行:

    <cache/>

    简单效果:

    (1)映射语句文件中的所有 select 语句将会被缓存。

    (2)映射语句文件中的所有 insert,update 和 delete 语句会刷新缓存。

    (3)缓存会使用 Least Recently Used(LRU,最近最少使用的)算法来收回。

    (4)根据时间表(比如 no Flush Interval,没有刷新间隔), 缓存不会以任何时间顺序 来刷新。

    缓存会存储列表集合或对象(无论查询方法返回什么)的 1024 个引用。

    缓存会被视为是 read/write(可读/可写)的缓存,意味着对象检索不是共享的,而 且可以安全地被调用者修改,而不干扰其他调用者或线程所做的潜在修改。

    强引用 ---> 弱引用 ---> 软引用 --> 虚引用

    前面我们说到,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。

    https://www.cnblogs.com/yuluoxingkong/p/8205858.html

    相关文章

      网友评论

          本文标题:mybatis一级缓存和二级缓存

          本文链接:https://www.haomeiwen.com/subject/lblelqtx.html