mybatis一些容易忽略的问题

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等操作,此级别内的二级缓存失效,不够精细。
  • 但是假设这个表的数据在别的地方被修改,或者联合修改,这里感知不到会有问题,又容易出错。