mybatis-redis源码: https://github.com/mybatis/redis-cache
mybatis-redis官网说明: http://www.mybatis.org/redis-cache/index.html
说明:
1、MyBatis默认开启二级缓存
2、MyBatis默认实现了自己的二级缓存(PerpetualCache),内部使用HashMap实现,无法实现分布式,并且服务器重启后就没有缓存了。
3、MyBatis二级缓存只适用于不常进行增、删、改的数据,比如国家行政区省市区街道数据。一但数据变更,MyBatis会清空缓存。因此二级缓存不适用于经常进行更新的数据。
4、MyBatis二级缓存是按命名空间(namespace)进行缓存的,可以指定某个命名空间下的sql进行缓存
5、MyBatis二级缓存的对象必须实现Serializable接口
步骤(以下配置已项目中缓存国家行政区省市区街道数据为例)
1、配置maven
配置jedis和mybatis-redis(实现了mybatis的cache接口的实现类),其他请自行配置(如:mybatis或mybatis-spring-boot-starter)
<!-- https://mvnrepository.com/artifact/redis.clients/jedis -->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.8.0</version>
</dependency>
<!-- 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.properties
mybatis-redis会自动读取redis.properties的配置(感兴趣的可以看源码)
#redis的服务器地址
host=127.0.0.1
#redis的服务端口
port=6379
#链接数据库
default.db=0
#客户端超时时间单位是毫秒
timeout=60000
#最大连接数
maxActive=300
#最大空闲数
maxIdle=100
#最小空闲数
minIdle=1
#最大建立连接等待时间
maxWait=1000
#指明是否在从池中取出连接前进行检验,如果检验失败,则从池中去除连接并尝试取出另一个
testOnBorrow=true
#当调用return Object方法时,进行有效性检查
testOnReturn=true
3、配置AreaDefaultMapperExt.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.tyb.saas.common.dal.dao.AreaDefaultMapper">
<!--
flushInterval(清空缓存的时间间隔): 单位毫秒,可以被设置为任意的正整数。
默认情况是不设置,也就是没有刷新间隔,缓存仅仅调用语句时刷新。
size(引用数目): 可以被设置为任意正整数,要记住你缓存的对象数目和你运行环境的可用内存资源数目。默认值是1024。
readOnly(只读):属性可以被设置为true或false。只读的缓存会给所有调用者返回缓存对象的相同实例。
因此这些对象不能被修改。这提供了很重要的性能优势。可读写的缓存会返回缓存对象的拷贝(通过序列化)。这会慢一些,但是安全,因此默认是false。
eviction(回收策略): 默认的是 LRU:
1.LRU – 最近最少使用的:移除最长时间不被使用的对象。
2.FIFO – 先进先出:按对象进入缓存的顺序来移除它们。
3.SOFT – 软引用:移除基于垃圾回收器状态和软引用规则的对象。
4.WEAK – 弱引用:更积极地移除基于垃圾收集器状态和弱引用规则的对象。
blocking(是否使用阻塞缓存): 默认为false,当指定为true时将采用BlockingCache进行封装,blocking,阻塞的意思,
使用BlockingCache会在查询缓存时锁住对应的Key,如果缓存命中了则会释放对应的锁,否则会在查询数据库以后再释放锁,
这样可以阻止并发情况下多个线程同时查询数据,详情可参考BlockingCache的源码。
type(缓存类):可指定使用的缓存类,mybatis默认使用HashMap进行缓存
-->
<cache type="org.mybatis.caches.redis.RedisCache" blocking="false"
flushInterval="0" readOnly="true" size="1024" eviction="FIFO"/>
<!--
useCache(是否使用缓存):默认true使用缓存
-->
<select id="find" parameterType="map" resultType="com.tyb.saas.common.api.model.dto.RspAreaInfo" useCache="true">
SELECT area_id AS areaId, area_name AS areaName
FROM t_area_default
WHERE 1=1
<choose>
<when test="areaParentId == null">
AND area_level = 1
</when>
<otherwise>
AND area_parent_id = #{areaParentId,jdbcType=INTEGER}
</otherwise>
</choose>
</select>
</mapper>
注:如果只配置<cache />则使用的是mybatis的默认二级缓存
如果只配置<cache type="org.mybatis.caches.redis.RedisCache" blocking="false" /> 则使用redis缓存,其他配置按默认
如果使用了mybatis generator生成了AreaDefaultMapper.xml,由于同一个命名空间只能配置一次缓存,无法在这个xml再配置一个缓存(会抛异常),因此这个xml要配:
<cache-ref namespace="com.tyb.saas.common.dal.dao.AreaDefaultMapper"/>
去引用AreaDefaultMapperExt.xml的缓存
以上即可
QA
Q1:能不能使用注解进行配置?A:能
在dao层的实现层使用@CacheNamespace注解
@CacheNamespace( implementation = org.mybatis.caches.redis.RedisCache.class)
(由于我自己的项目用mybatis代理实现类,没有dao的实现层,所有这个我没测,直接在dao层架注解是没用的)
Q2:能不能自己实现缓存?A:能
MyBatis有提供Cache接口,自己实现Cache接口就行