MyBatis缓存

MyBatis提供了数据缓存支持,依据数据缓存的有效范围默认定义了一级缓存和二级缓存

一级缓存

该级缓存默认开启,不能关闭;

该级缓存为SqlSession级别的缓存,也称为本地缓存;

以下面为例。在同一 Session 里执行同一个查询两次,控制台日志只有一个查询

 以下4种情况将会导致该级缓存失效

a、在不同SqlSession中查询数据;

 

 b、相同SqlSession中查询数据,但查询条件不同

c、相同SqlSession中查询数据,但两次查询之间执行了增删改操作 

 

 d、相同SqlSession中查询数据,但第二次查询前,程序调用SqlSession对象clearCache()方法手动清除了一级缓存

 

 二级缓存

该级缓存默认不开启,但如果使用二级缓存需要在每个XML映射文件中添加<cache></cache>以配置该级缓存。二级缓存可以通过在全局配置文件配置setting标签来关闭该级缓存。

    cache标签属性:

    eviction:缓存回收策略:

    LRU – 最近最少使用的:移除最长时间不被使用的对象,默认值

    FIFO – 先进先出:按对象进入缓存的顺序来移除它们。

    SOFT – 软引用:移除基于垃圾回收器状态和软引用规则的对象。

    WEAK – 弱引用:更积极地移除基于垃圾收集器状态和弱引用规则的对象。

    flushInterval:刷新间隔,单位毫秒,默认情况是不设置,也就是没有刷新间隔,缓存仅仅调用语句时刷新

    size:引用数目,正整数,代表缓存最多可以存储多少个对象,太大容易导致内存溢出

    readOnly:只读,默认为false。true:只读缓存;会给所有调用者返回缓存对象的相同实例,速度快;false:读写缓存;会返回缓存对象的拷贝(通过序列化),速度慢但安全。

该级缓存为namespace级别的缓存

工作机制:通过SqlSession查询数据,这些数据将会放到当前会话的一级缓存中;如果当前会话关闭,则一级缓存中的数据会被保存到二级缓存中,此后新的SqlSession将从二级缓存中查找数据;

例如我们在下面的 user_info.xml中加入 <cache>标签。

这个时候我们还需要对 vo 类进行序列化一下。

 

 

 可以看到二级缓存实现了跨Session 操作。在不同的Session中执行同一个操作,可以直接从二级缓存得到数值。

 

 而在中间加入增删改操作会导致清除二级缓存,然后再次进行查询,如下。

 

 

 而当我们在xml中配置<cache>之后,可以对下面的数据库操作标签添加属性。select标签的useCache属性用于设置是否使用二级缓存;insert、update、delete或select标签均有flushCache属性,其中增删改默认true,即sql执行以后,会同时清空一级和二级缓存,查询默认false。

我们将 delete 的flushCache 改为false 即执行之后不清缓存。

 

 

 

 可以看出如果设置成fasle 不清除缓存,最后查询的结果会出错。在删除了一个元素之后,查询的个数依然没有变化。

所以一般我们不会改变默认值true。

但这也是Mybatis 缓存的一个缺点,他在清除二级缓存时,清除的是所有的二级缓存,然后再获取数据,如果缓存中的数据非常多的情况下,会对资源造成极大的浪费。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章