mybatis二级缓存
1、mybatis缓存使用场景
2、二级缓存定义
二级缓存也称做是应用级缓存,与一级缓存不同的是它的作用范围是整个应用,而且可以跨线程使用。所以二级缓存有跟高的命中率,适合缓存一些修改较小的数据。
3、二级缓存拓展性需求
硬盘:持久化
第三方集成:redis等
4、装饰器+责任链实现二级缓存 屏蔽了底层复杂性
synchronized cache装饰了后边的所有对象,一层一层嵌套,每个对象实现一个功能,所以叫责任链模式。
scheduled 是判断缓存的时间,当时间到了之后,就会清空缓存
扩展性强,可以随时在责任链中加上一个节点。
/** * @CacheNamespace(readWrite =false) true 序列化 false 非序列化 synchronized sche */ @Test public void cacheTest4() { Cache cache = configuration.getCache("org.coderead.mybatis.UserMapper"); User user = Mock.newUser(); cache.putObject("zhangsan", user);// 设置缓存 // 线程1 如果经过了序列换,两个线程读出来的对象是不同的,虽然值是相同的,这样保证了安全性。两个线程对对象的操作不会互相影响 Object zhangsan = cache.getObject("zhangsan"); // 线程2 Object zhangsan = cache.getObject("zhangsan"); System.out.println(luban==luban1); }
5、缓存的配置策略:
缓存的配置策略在CacheNamespace接口中完成,也就是默认使用的责任链中的节点类。。如果需要自定义节点,只需要实现对应的接口极了
public @interface CacheNamespace { Class<? extends org.apache.ibatis.cache.Cache> implementation() default PerpetualCache.class; Class<? extends org.apache.ibatis.cache.Cache> eviction() default LruCache.class; long flushInterval() default 0; int size() default 1024; boolean readWrite() default true; boolean blocking() default false; /** * Property values for a implementation object. * @since 3.4.2 */ Property[] properties() default {};
自定义二级缓存配置.
6、二级缓存的命中
flushcache 为true会清空所有缓存。
必须手动提交(commit、close)才会触发二级缓存。
@Test public void cacheTest5() { // 查询1 SqlSession session1 = factory.openSession(true); UserMapper mapper1 = session1.getMapper(UserMapper.class); mapper1.selectByid3(10);// 重用执行器 /* // flush cache清空 User user = mapper1.selectByid(10); //清空了,提交 */ session1.commit();//提交才能命中 // 查询2 SqlSession session2 = factory.openSession(); UserMapper mapper2 = session2.getMapper(UserMapper.class); User use2 = mapper2.selectByid3(10); }
7、为什么二级缓存提交之后才能命中
因为二级缓存是跨线程使用的,为了防止脏读
8、二级缓存低层实现结构
一个缓存区就是一个责任链。一个会话持有一个事务缓存管理器,只有当会话进行commit之后才会从暂存区提交到缓存区,也就是只有commit之后才会触发二级缓存。
9、缓存命名空间的概念
一个mapper 通过@CacheNamespace来声明为一个缓存空间。
10.二级缓存执行流程