使用缓存可以使应用更快的获取数据,避免频繁的数据库交互,尤其是在查询越多,缓存命中率越高的情况下,使用缓存的作用就很明显。
mybatis缓存源码分析
也叫本地缓存。存在与sqlsession的生命周期中,在同一个sqlsession查询时,MyBatis会把执行的方法和参数通过算法生成缓存的键值,将键值和查询结果存储到Map对象中。如果同一个sqlsession中执行的方法和 参数完全相同,那么通过算法会生成完全一致的键值(Map),当map缓存对象中存在该键值时,返回缓存中的对象。
当进行insert、update、delete操作时,MyBatis会清空一级缓存。
存在的问题:假如在一个sqlSession中存在两个完全相同的查询操作,那么按照一级缓存,这两个查询返回的应该是同一个对象。此时如果在第一个查询获取返回值后,对该返回值进行了修改且没有进行持久化,那么第二次查询的结果就会变为修改后的内容,产生脏数据。
如果不希望让查询语句使用以及缓存,可以再mapper文件中对应的select标签中加入flushCache = "true",(但是不推荐)
mybatis二级缓存非常强大,它不同于一级缓存只存在于SqlSession的生命周期中,可以理解为存在于SqlSessionFactory的生命周期中。当存在多个SqlSessionFactory时,它们的缓存是绑定在各自的对象上的,缓存数据之间一般不相通。
在mybatis-config.xml的settings中配置
Mybatis的二级缓存是和命名空间绑定的,即二级缓存需要配置在*Mapper.xml中或者*Mapper.java接口中。给出这两种方式的配置示例:
*Mapper.xml
*Mapper.java
@CacheNamespace(
eviction = FifoCache.class,
flushInterval = 60000,
size = 512,
readWrite = true
)
public interface UserMapper {
//接口方法
}
配置二级缓存后会有如下效果:
cache可以配置的属性如下:
1.eviction(收回策略):
2.flushInterval(刷新间隔):可以被设置为任意的正整数,默认不设置,代表不刷新,缓存仅仅在调用sql语句时刷新;
3.size(引用数目):可以被设置为任意正整数,默认值为1024;
readonly(只读):可以被设置为true或false,只读的缓存会给所有调用者返回相同的缓存对象,因此这些对象不能修改,这提供了很重要的性能优势;可读写的缓存会通过序列化返回缓存对象的拷贝,这种方式会慢一些,但是安全。因此默认是false;
当同事在*Mapper.xml和*Mapper.java中配置二级缓存时,会抛出一个异常:
org.apache.ibatis.builder.BuilderException: Error parsing SQL Mapper Configuration.Cause : java.lang.IllegalArgumentException: Caches collection already contains value for tk.mybatis.simple.mapper.RoleMapper
这是因为Mapper接口和对应的XML文件是相同的命名空间,想使用二级缓存,二者必须同时配置。这时应该使用参照缓存:
Mapper接口参照XML文件:将mapper接口的二级缓存改为:
/**
* @Author:YR123
* @Date:2019/3/19 14:16
* @Description:
*/
@CacheNamespaceRef(UserMapper.class)
public interface UserMapper {
//接口方法
}
XML文件参照Mapper接口:将XML文件的配置改为:
EhCache是一个纯粹的java进程内缓存框架,具有快速,精干等特点。有以下特性:
1.添加项目依赖
在pom.xml中添加依赖
org.mybatis.caches
mybatis-ehcache
1.0.3
2.配置EhCache
在src/main/resources目录下新增ehcache.xml文件
其中可以看到配置中有一个默认的cache配置和一个指定了name的cache配置,这个name配置会去寻找nameSpace等于此值的RoleMapper.xml配置文件。
3.修改*Mapper.xml(nameSpace=“xxxxx”的mapper文件)
如果存在cache标签就将其注释掉,然后加入以下内容
MyBatis项目开发者提供了Redis的MyBatis二级缓存实现,该项目名为redis-cache,
项目地址为https://github.com/mybatis/redis-cache
1.添加pom依赖
org.mybatis.caches
mybatis-redis
1.0.0-beta2
2.配置redis
简而言之,使用redis缓存需要在本地安装redis服务,参考:Redis学习(一)、windows环境下的redis安装和部署
Redis服务启动后,在src/main/resources目录下新增redis.properties文件
host=localhost
port=6379
connectionTimeout=5000
soTimeout=5000
password=
database=0
clientName=
3.修改*Mapper.xml中的缓存配置
4.注意的点
redisCache在保存缓存数据和获取缓存数据时,使用了java的序列化和反序列化,因此需要保证被缓存的对象实现java的Serializable接口。