mybatis——缓存

在mybatis中,缓存的使用是一个十分重要的过程,在项目查询配置过程中,有着很重要的作用。缓存分为一级缓存和二级缓存,一级缓存是默认缓存的。

缓存

MyBatis 包含一个非常强大的查询缓存特性,它可以非常方便地配置和定制。 MyBatis 3中的缓存实现的很多改进都已经实现了,使得它更加强大而且易于配置。
默认情况下是没有开启缓存(二级缓存)的,除了局部的 session 缓存(一级缓存是默认开启的),可以增强变现而且处理循环依赖也是必须的。要开启二级缓存,你需要在你的 SQL 映射文件(mapper)中添加一行:

字面上看就是这样。这个简单语句的效果如下:

1、 映射语句文件中的所有 select 语句将会被缓存。
2、映射语句文件中的所有 insert, update 和 delete 语句会刷新缓存。
3、缓存会使用 Least Recently Used( LRU,最近最少使用的)算法来收回。
4、根据时间表(比如 no Flush Interval,没有刷新间隔),缓存不会以任何时间顺序
来刷新。
5、 缓存会存储列表集合或对象(无论查询方法返回什么)的 1024(默认) 个引用。
6、 缓存会被视为是 read/write(可读/可写)的缓存,意味着对象检索不是共享的,而且可以安全地被调用者修改,而不干扰其他调用者或线程所做的潜在修改。
所有的这些属性都可以通过缓存元素的属性来修改。比如:

<cache eviction="FIFO" flushInterval="60000" size="512" readOnly="true"/>

这个更高级的配置创建了一个 FIFO 缓存,并每隔 60 秒刷新, 存数结果对象或列表的
512 个引用,而且返回的对象被认为是只读的,因此在不同线程中的调用者之间修改它们会
导致冲突。
可用的收回策略有:

 LRU – 最近最少使用的:移除最长时间不被使用的对象。
 FIFO – 先进先出:按对象进入缓存的顺序来移除它们。
 SOFT – 软引用:移除基于垃圾回收器状态和软引用规则的对象。
 WEAK – 弱引用:更积极地移除基于垃圾收集器状态和弱引用规则的对象。

默认的是 LRU。
flushInterval(刷新间隔)可以被设置为任意的正整数,而且它们代表一个合理的毫秒
形式的时间段。默认情况是不设置,也就是没有刷新间隔,缓存仅仅调用语句时刷新。
size(引用数目)可以被设置为任意正整数,要记住你缓存的对象数目和你运行环境的
可用内存资源数目。默认值是 1024。
readOnly(只读)属性可以被设置为 true 或 false。只读的缓存会给所有调用者返回缓
存对象的相同实例。因此这些对象不能被修改。这提供了很重要的性能优势。可读写的缓存会返回缓存对象的拷贝(通过序列化)。这会慢一些,但是安全,因此默认是 false。

使用自定义缓存

除了这些自定义缓存的方式,你也可以通过实现你自己的缓存或为其他第三方缓存方案
创建适配器来完全覆盖缓存行为。

<cache type=”com.domain.something.MyCustomCache”/>

这个示例展示了如何使用一个自定义的缓存实现。 type 属性指定的类必须实现
org.mybatis.cache.Cache 接口。这个接口是 MyBatis 框架中很多复杂的接口之一,但是简单给定它做什么就行。

public interface Cache {
String getId();
int getSize();
void putObject(Object key, Object value);
Object getObject(Object key);
boolean hasKey(Object key);
Object removeObject(Object key);
void clear();
ReadWriteLock getReadWriteLock();
}

要配置你的缓存,简单和公有的 JavaBeans 属性来配置你的缓存实现,而且是通过 cache元素来传递属性,比如,下面代码会在你的缓存实现中调用一个称为“ setCacheFile(String file)”的方法:

<cache type=”com.domain.something.MyCustomCache”>
<property name=”cacheFile” value=/tmp/my-custom-cache.tmp”/>
</cache>

你可以使用所有简单类型作为 JavaBeans 的属性, MyBatis 会进行转换。
记得缓存配置和缓存实例是绑定在 SQL 映射文件的命名空间是很重要的。因此,所有
在相同命名空间的语句正如绑定的缓存一样。语句可以修改和缓存交互的方式,或在语句的基础上使用两种简单的属性来完全排除它们。 默认情况下,语句可以这样来配置:

<select ... flushCache=”false” useCache=”true”/>
<insert ... flushCache=”true”/>
<update ... flushCache=”true”/>
<delete ... flushCache=”true”/>

因为那些是默认的,你明显不能明确地以这种方式来配置一条语句。相反,如果你想改
变默认的行为,只能设置 flushCache 和 useCache 属性。比如,在一些情况下你也许想排除从缓存中查询特定语句结果,或者你也许想要一个查询语句来刷新缓存。相似地,你也许有一些更新语句依靠执行而不需要刷新缓存。

参照缓存

回想一下上一节内容,这个特殊命名空间的唯一缓存会被使用或者刷新相同命名空间内
的语句。也许将来的某个时候,你会想在命名空间中共享相同的缓存配置和实例。在这样的
情况下你可以使用 cache-ref 元素来引用另外一个缓存。

<cache-ref namespace=”com.someone.application.data.SomeMapper”/>

mybatis整合ehcache

ehcache是一个分布式缓存框架。

EhCache 是一个纯Java的进程内缓存框架,是一种广泛使用的开源Java分布式缓存,具有快速、精干等特点,是Hibernate中默认的CacheProvider。

分布缓存

我们系统为了提高系统并发,性能、一般对系统进行分布式部署(集群部署方式)不使用分布缓存,缓存的数据在各各服务单独存储,不方便系统开发。所以要使用分布式缓存对缓存数据进行集中管理。mybatis无法实现分布式缓存,需要和其它分布式缓存框架进行整合。

整合方法(掌握无论整合谁,首先想到改type接口)

mybatis提供了一个cache接口,如果要实现自己的缓存逻辑,实现cache接口开发即可。mybatis和ehcache整合,mybatis和ehcache整合包中提供了一个cache接口的实现类。

二级应用场景

对于访问多的查询请求且用户对查询结果实时性要求不高,此时可采用mybatis二级缓存技术降低数据库访问量,提高访问速度,业务场景比如:耗时较高的统计分析sql、电话账单查询sql等。

实现方法如下:通过设置刷新间隔时间,由mybatis每隔一段时间自动清空缓存,根据数据变化频率设置缓存刷新间隔flushInterval,比如设置为30分钟、60分钟、24小时等,根据需求而定。

二级缓存局限性

mybatis二级缓存对细粒度的数据级别的缓存实现不好,对同时缓存较多条数据的缓存,比如如下需求:对商品信息进行缓存,由于商品信息查询访问量大,但是要求用户每次都能查询最新的商品信息,此时如果使用mybatis的二级缓存就无法实现当一个商品变化时只刷新该商品的缓存信息而不刷新其它商品的信息,因为mybaits的二级缓存区域以mapper为单位划分,当一个商品信息变化会将所有商品信息的缓存数据全部清空。解决此类问题需要在业务层根据需求对数据有针对性缓存。需要使用三级缓存

你可能感兴趣的:(session,mybatis,缓存)