文章仅用于自己总结学习,总结于hollis分享。
Mybatis有缓存机制包括:一级缓存,二级缓存两种。
一级缓存
在同一个会话中,Mybatis回将已经执行了的SQL语句缓存到内存,下次执行相同sql语句时,会先查看缓存中是否存在该结果,如果存在则直接返回,不在执行sql语句。
一级缓存默认开启,可以通过mybatis的配置文件中设置禁用或刷新缓存来控制缓存的使用。
注意:
- mybatis一级缓存内部设计就是一个没有容量限定的HashMap。
- mybatis一级缓存最大范围是SqlSession内部,有多个SqlSession或者分布式环境下,数据写操作会引起脏数据,简言之,当一个SqlSession查询并缓存结果后,另一个SqlSession更新了该数据,其他缓存结果的SqlSession是看不到更新后的数据的。建议设定缓存级别为Statement。
二级缓存
二级缓存是基于命名空间的缓存,他可以跨会话,在多个会话之间共享缓存,可以减少数据库的访问次数。
要使用二级缓存需要在mybatis的配置文件中配置相应的缓存实现类,并在需要使用缓存的Mapper接口上添加@CacheNamespace注解。
二级缓存的使用需要之一缓存的更新和失效机制,以及并发操作问题。
注意:
因为二级缓存是基于namespace的,所以一般情况下,mybatis的二级缓存是不适合多表查询的情况的。举个栗子:
现在有两张表:student和class,我们为两张表创建两个namespace去对这两个表做相关的操作。同时进行多表查询,我们在namespace = student的空间中,对student和class两张表做关联查询操作(sqlA)。此时就会在namespace = student的空间中把sqlA的结果缓存下来,如果我们在namespace = class下更新class表,namespace = student是不会更新的,这就会导致脏数据的产生。