一、一级缓存
Mybatis 的一级缓存是指Session缓存。一级缓存的作用域默认是SqlSession。Mybatis默认开启一级缓存。
在同一个SqlSession中,执行相同的查询SQL,第一次会去数据库进行查询,并写到缓存中;第二次以后则直接去一级缓存中取。
当执行的SQL查询中间发生了增删改的操作,mybatis会把SqlSession的缓存清空。
一级缓存失效的情况
- SqlSession不同;
- SqlSession相同,查询条件不同。因为缓存条件不同,缓存中还没有数据。
- SqlSession相同,在两次相同查询条件中间执行过增删改操作。
- SqlSession相同,手动清空了一级缓存。(如果SqlSession去执行commit操作(执行插入。更新、删除),清空SqlSession中的一级缓存,这样做的目的是为了让缓存中存储的是最新的消息,避免脏读。)
二、二级缓存
Mybatis的二级缓存是指mapper映射文件。二级缓存的作用域是同一个nameSpace下的mapper映射文件内容,多个SqlSession共享。Mybatis需要手动设置启动二级缓存。
一个会话,查询一条数据,这个数据会被放在当前会话的一级缓存中;如果会话被关闭了,一级缓存汇总的数据会被保存到二级缓存。新的会话查询信息就会参照二级缓存。
二级缓存的使用原则
- 只能在一个命名空间下使用二级缓存。由于二级缓存中的数据是基于nameSpace的,即不同nameSpace中的数据互不干扰。在多个nameSpace中若均存在对同一个表的操作,那么这多个nameSpace中的数据可能就会出现不一致现象。
- 在单表上使用二级缓存。如果一个表与其他表有关联关系,那么就非常有可能存在多个nameSpace对同一数据的操作。而不同nameSpace中的数据互不干扰,所以就有可能出现多个nameSpace中的数据不一致现象。
- 查询多于修改时使用二级缓存。在查询操作远远多于增删改操作的情况下可以使用二级缓存。因为任何增删改操作都将刷新二级缓存,对二级缓存的频繁刷新将降低系统性能。
三、mybatis有二级缓存,为什么还要用redis???
- mybatis一级缓存作用域是session,session在commit之后缓存就消失了。
- mybatis二级缓存作用域是sessionFactory,该缓存是以nameSpace为单位的(也就是一个Mapper.xml文件),不同nameSpace下操作互不影响。
- 所有对数据表的改变操作都会刷新缓存,但是一般不用二级缓存。例如,在UserMapper.xml中有大多数针对User表的操作,但是在另外一个XXXMapper.xml中,还有针对user单表的操作,这会导致user在两个命名空间下的数据不一致。
- 如果UserMapper.xml中做了刷新缓存的操作,在XXXMapper.xml中缓存依然有效,如果针对user单表查询,使用缓存的结果可能会不正确,读到脏数据。
- redis很好的解决了这个问题,而且比之一、二级缓存的更好,redis可以搭建在其他服务器上,缓存容量可扩展,redis可以灵活的使用在需要的缓存数据上。