概述

mybatis提供了缓存机制减轻数据库压力,提高数据库性能。mybatis的缓存分为两级:一级缓存、二级缓存。
一级缓存是SqlSession级别的缓存,缓存的数据只在SqlSession内有效。
二级缓存是mapper级别的缓存,同一个namespace共用一个缓存,所以对SqlSession是共享的。

1VSh0s.png

一级缓存

一级缓存默认是开启状态的。
1VSrkt.png

一级缓存的生命周期

  • mybatis在开启一个数据库会话的时,会创建一个新的SqlSession对象,SqlSession对象中会持有一个Executor对象,Executor对象中持有一个新的PerpetualCache对象;当会话结束时SqlSession对象及其内部的Executor对象还有perpetualChache对象也会被释放掉。
  • SqlSession调用了close()方法,会释放掉一级缓存PerpetualCache对象,一级缓存将不可使用。
  • 如果SqlSession调用了clearCache(),会清空PerpetualCache对象中的数据(缓存数据),但是一级缓存仍然是可用的,只是之前的数据被清空了。
  • SqlSession中执行了任何一个update操作,都会清空perpetualCache对象的数据,但是该对象可以继续使用。

如何判断两次查询时完全相同的?

mybaits认为,对于两次查询,如果以下条件都完全一样,那么就任务它们是完全相同的两次查询。

  • 传入的statementId
  • 查询时要求的结果集的结果的范围
  • 查询传递给JDBC的sql语句字符串
  • 传递给java.sql.Statement要设置的参数值。

二级缓存

mybatis的二级缓存是application级别的缓存,它可以提高数据库查询的效率,以提高应用的性能。
二级缓存默认是不开启的。如果需要开启二级缓存,需要进行配置,并且要求返回的pojo必须是可序列化的。
如果开启了二级缓存:

  • 映射语句文件中的所有select语句将会被缓存
  • 映射语句文件中的所有insert,update和delete语句会刷新缓存。
  • 缓存会使用默认的LRU算法来回收。
  • 根据时间表,缓存不会以任何时间顺序来刷新。
  • 缓存会存储列表集合或对象的1024个引用。
  • 缓存会被视为可读可写的缓存,意味着对象检索是不共享的,而且可以安全的被调用者修改,不干扰其它调用者或线程所做的潜在修改。

如何开启二级缓存

  1. 首先查询返回的pojo类必须要实现Serializable即可,表示式可序列化的。
  2. 在对应的mapper文件中开启缓存。
1
<cache eviction="LRU" readOnly="true" flushInterval="6000" size="1024"/>

cache标签有几个属性需要注意:

  • eviction:设置缓存的清除策略,默认值为LRU
    • LRU:最近最少使用:移除最长时间不被使用的对象。
    • FIFO:先进先出:按对象进入缓存的顺序来移除 它们
    • SOFT:软引用:基于垃圾回收器状态和软引用规则移除对象。
    • WEAK:弱引用:更积极的基于浪迹回收器状态和如弱引用规则移除对象。
  • flushInterval:刷新间隔,默认清空下为不设置,自会在特定语句时刷新缓存
  • size:引用数目,默认是1024
  • readOnly:只读属性,设置为只读的比可写的性能更高,避免了对缓存对象的拷贝。
  1. 在全局配置文件中开启二级缓存
1
2
3
<settings>
<setting name="cacheEnabled" value="true"/>
</settings>