mybatis缓存
一级缓存
一级缓存默认开启
一级缓存是基于session的,执行插入、更新、删除等操作会清空缓存
简单分析:
1.sqlSession.getMapper(**Mapper.class); 生成mapper代理对象
2.执行mapper方法的时候,调用代理对象的invoke方法,即MapperProxy中的invoke
3.invoke方法中的execute方法通过各种判断,调用 sqlSession 接口中的方法
4.sqlSession 中会调用 executor 执行器接口中的方法1)先生成cacheKey
2)再query方法中,先尝试从缓存 localCache 中获取,如果没有,则从数据库中查询 queryFromDatabase
3)queryFromDatabase 中将查询结果放入 localCache 中
二级缓存
二级缓存的原理和一级缓存原理一样,第一次查询,会将数据放入缓存中,然后第二次查询则会直接去缓存中取。
但是一级缓存是基于sqlSession的,而二级缓存是基于mapper文件的namespace的,也就是说多个sqlSession可以共享一个mapper中的二级缓存区域,
并且如果两个mapper的namespace相同,即使是两个mapper,那么这两个mapper中执行sql查询到的数据也将存在相同的二级缓存区域中
1.开启二级缓存
默认不开启,需要手动开启
<!-- sqlMapConfig.xml中 -->
<settings>
<setting name="cacheEnabled" value="true"/>
</settings>
<!-- **Mappre.xml中
我们可以看到mapper.xml文件中就这么一个空标签,其实这里可以配置,PerpetualCache这个类是
mybatis默认实现缓存功能的类。我们不写type就使用mybatis默认的缓存,也可以去实现Cache接口
来自定义缓存 -->
<cache></cache>
看源码,我们发现,二级缓存其实也是一个Map
2.useCache和flushCache
- userCache 是用来设置是否禁用二级缓存,在statement中设置useCache=false可以禁用当前select语句的二级缓存
- flushCache=“true”属性,默认情况下为true,即刷新缓存,如果改成false则不会刷新
3.二级缓存整合redis
- 引入依赖
<dependency> <groupId>org.mybatis.caches</groupId> <artifactId>mybatis-redis</artifactId> <version>1.0.0-beta2</version> </dependency>
- **Mapper.xml
<cache type="org.mybatis.caches.redis.RedisCache" />
- redis.properties
redis.host=localhost redis.port=6379 redis.connectionTimeout=5000 redis.password= redis.database=0
ps: 一级和二级缓存在单体应用时有用,在分布式、分库分表情况下,可以说很鸡肋,尤其二级缓存容易造成脏读现象,不建议使用