Mybatis缓存的问题#
一级缓存#
默认开启,和session的生命周期相同,一般一个session和一个线程绑定。如果在同一个线程里面进行重复查询会使用缓存。
- 但是和spring融合之后就会失效:
- 因为myabatis和spring融合的时候,mabatis提供了一个
mabatis-spring-xxx.jar
,里面提供了一个类叫做SqlSessionTemplate
代理替代了mybatis中默认的SqlSession实现DefaultSqlSession
,是对DefaultSqlSession
的一个增强。这个类在容器启动的时候注入给了mapper,同时它在代理的代码中把session关闭了,所以session执行一次就关闭,无法使用一级缓存。 - 为什么要关闭?mybatis为什么不关闭,因为用户自己拿到sqlSession,
DefaultSqlSession
暴露给用户了,可以自己任意时候关闭,充分利用一级缓存。spring没有把sesqlSession直接暴露给用户,所以每次执行完必须要关,防止用户忘记关闭造成泄漏。 - mapper交给spring来生成代理,sessionFactory也给spring,每次query他都会去开启一个session。
- 也就是spring给sqlSession做了一次代理,sqlSession放到了代理中,每次调用完毕他就把sqlsession给关闭了。这样即使在service一个方法中调用dao进行多次同样的query也不会使用缓存。也就是会失效。
二级缓存#
@CacheNamespace
注解放到mapper上即可开启。但是名字就能看出来他是一个Namespace级别隔离的。
- 在同一个namespace内进行update、delete、insert等操作,此级别内的二级缓存失效,不够精细。
- 但是假设这个表的数据在别的地方被修改,或者联合修改,这里感知不到会有问题,又容易出错。