-
前言
1、mybatis整合spring,一级缓存会失效,mybatis会在每次查询之后自动关闭sqlSession。
2、二级缓存多线程共享,开启方式(注解)@CacheNamespace或者在xml文件中开启,开启方式为<settingname='cacheEnabled'value='true'/>
3、二级缓存有一个很大的坑,缓存是针对命名空间而言的,也就是说如果你创建了两个Mapper对象,那么两个Mapper之间的缓存是不共用的。并且mybatis的缓存只适用单机环境,如果需要在分布式系统中实现缓存,只能借助第三方的缓存。
-
正文
今天看mybatis源码的时候,发现了spring整个mybatis和单独使用mybatis的区别,既一级缓存失效的问题,做个记录:
一:针对单独使用mybatis的情况
在查询的地方打断点,这边我直接到org.apache.ibatis.binding.MapperMethod.executeForMany()打断点,可以看到这里是调用org.apache.ibatis.session.defaults.DefaultSqlSession的selectList()方法:
我们点进去看,发现还是调用mybatis的org.apache.ibatis.session.defaults.DefaultSqlSession的selectList()方法,直接查询
记住这段代码,我们来看mybatis集成spring后代码有什么变化。
二:针对使用mybatis-spring的情况
我们一样走到这个方法:
可以看到调用的是org.mybatis.spring.SqlSessionTemplate.selectList()方法,我们继续往下走:
可以看到它里面又一个私有的内部类实现了InvocationHandler,总结来说,SqlSessionTemplate是DefaultSqlSession的增强类,里面不直接调用CURD方法,而是通过一个代理对象,增强了你所调用的方法,并且,做了扩展,那mybatis是什么时候换了这个对象的呢?我们会在一篇文章着重讲解,现在关键来看这段代码:
在finally代码块中,mybatis把sqlSession关闭了,所以每次查询都会创建新的sqlSession,所以一级缓存根本不生效。