Mybatis的二级缓存是和命名空间绑定的,所以通常情况下每个Mapper映射文件都拥有自己的二级缓存,不同Mapper的二级缓存互不影响。在以下场景中,推荐使用二级缓存:
(1)以查询为主的应用中,只有尽可能少的增、删、改操作。
(2)绝大多数以单表操作存在时,由于很少存在相互关联的情况,因此不会出现脏数据。
(3)可以按业务划分对表进行分组时,如关联的表比较少,可以通过参照缓存(让几个相互关联的ER表同时使用同一个二级缓存)进行配置。
在Mybatis的全局配置settings中有一个参数cacheEnabled,这个参数是二级缓存的全局开关,默认值是true,初始状态是启用状态。如果想要配置,可以在mybatis-config.xml中写如下代码:
<settings>
<!-- 全局映射器启用缓存 -->
<setting name="cacheEnabled" value="true" />
</settings>
集成Redis缓存
我们使用Mybatis官方提供的redis-cache集成Redis数据库,步骤如下。
1、添加项目依赖
在pom.xml中添加如下依赖:
<!-- https://mvnrepository.com/artifact/org.mybatis.caches/mybatis-redis -->
<dependency>
<groupId>org.mybatis.caches</groupId>
<artifactId>mybatis-redis</artifactId>
<version>1.0.0-beta2</version>
</dependency>
2、配置Redis
使用Redis前,必须有一个Redis服务,有关Redis安装启动的相关内容,自行百度。
Redis服务启动后,在Maven项目的src/main/resources目录下新增redis.properties文件。
host=localhost
port=6379
connectionTimeout=5000
soTimeout=5000
password=
database=0
clientName=
上面这几项是redis-cache项目提供的可以配置的参数,这里配置了服务器地址、端口和超时时间。
3、修改XXXMapper.xml中的缓存配置
<mapper namespace="test.dao.XXXMapper">
<cache type="org.mybatis.caches.redis.RedisCache" eviction="FIFO" flushInterval="60000" size="512" readOnly="true" />
</mapper>
默认的二级缓存会有如下效果:
(1)映射语句文件中的所有select语句将会被缓存。
(2)映射语句文件中的所有insert、update、delete语句会刷新缓存。
(3)缓存会使用Least Recently Used(LRU,最近最少使用)算法来收回。
(4)根据时间表(no Flush Interval,没有刷新间隔),缓存不会以任何时间顺序来刷新。
(5)缓存会存储集合或对象(无论查询方法返回什么类型的值)的1024个引用。
(6)缓存会被视为read/write(可读/可写)的,意味着对象检索不是共享的,而且可以安全的被调用者修改,而不干扰其他调用者或线程所做的潜在修改。
上面这个例子更高级的配置创建了一个 FIFO 缓存,并每隔 60 秒刷新,存数结果对象或列表的 512 个引用,而且返回的对象被认为是只读的,因此在不同线程中的调用者之间修改它们会导致冲突。
cache可以配置的属性如下:
1、eviction(收回策略)有, 默认的是 LRU:
(1)LRU – 最近最少使用的:移除最长时间不被使用的对象。
(2)FIFO – 先进先出:按对象进入缓存的顺序来移除它们。
(3)SOFT – 软引用:移除基于垃圾回收器状态和软引用规则的对象。
(4)WEAK – 弱引用:更积极地移除基于垃圾收集器状态和弱引用规则的对象。
2、flushInterval(刷新间隔)可以被设置为任意的正整数,而且它们代表一个合理的毫秒形式的时间段。默认情况是不设置,也就是没有刷新间隔,缓存仅仅调用语句时刷新。
3、 size(引用数目)可以被设置为任意正整数,要记住你缓存的对象数目和你运行环境的可用内存资源数目。默认值是1024。
4、 readOnly(只读)属性可以被设置为true或false。只读的缓存会给所有调用者返回缓存对象的相同实例。因此这些对象不能被修改。这提供了很重要的性能优势。可读写的缓存会返回缓存对象的拷贝(通过序列化)。这会慢一些,但是安全,因此默认是false。
当需要分布式部署应用时,如果使用Mybatis自带缓存或基础的Ehcache缓存,分布式应用会各自拥有自己的缓存,他们之间不会共享缓存,这种方式会消耗更多的服务器资源。如果使用类似类似Redis的缓存服务,就可以将分布式应用连接到同一个缓存服务器,实现分布式应用间的缓存共享。