1 一级缓存(默认开启缓存(开发时要开启事务@Transactional(rollbackFor = Exception.class)才会真正使用到一级缓存))
同一个
SqlSession
对象, 在参数和 SQL 完全一样的情况先, 只执行一次 SQL 语句(如果缓存没有过期)
默认一级缓存失效情况:
1、SqlSession不同
2、SqlSession相同
1)查询条件不同(当前一级缓存中没有这个数据)
2)两次查询之间执行了增删改查操作
3)手动清除了一次缓存session.clearCache()
2. 二级缓存的原理(多个sqlSession可以共享一个mapper中的二级缓存区域,需手动开启)
mybatis中的二级缓存是mapper级别的缓存,值得注意的是,不同的mapper通常情况下有不同的namespace,就都有一个二级缓存,也就是说,不同的mapper之间的二级缓存是互不影响的。为了更加清楚的描述二级缓存,先来看一个示意图:
从图中可以看出:
- sqlSession1去查询用户id为1的用户信息,查询到用户信息会将查询数据存储到该UserMapper的二级缓存中。
- 如果SqlSession3去执行相同 mapper下sql,执行commit提交,则会清空该UserMapper下二级缓存区域的数据。
- sqlSession2去查询用户id为1的用户信息,去缓存中找是否存在数据,如果存在直接从缓存中取出数据。
缓存的执行原理和前面提到的一级缓存是差不多的,二级缓存与一级缓存区别在于二级缓存的范围更大,多个sqlSession可以共享一个mapper中的二级缓存区域。mybatis是如何区分不同mapper的二级缓存区域呢?它是按照不同mapper有不同的namespace来区分的,也就是说,如果两个mapper的namespace相同,即使是两个mapper,那么这两个mapper中执行sql查询到的数据也将存在相同的二级缓存区域中。
2. 二级缓存的使用
明白了mybatis中二级缓存的原理后,接下来就是如何使用二级缓存了。在使用之前,首先得开启二级缓存的开关。
2.1 开启二级缓存
由于mybaits的二级缓存是mapper范围级别,所以除了在SqlMapConfig.xml设置二级缓存的总开关外,还要在具体的mapper.xml中开启二级缓存。设置如下:
这是在SqlMapConfig.xml中设置的,还得在具体的mapper.xml中设置,如下:
可以看到,具体的mapper中仅仅就一个<cache>
标签,并没有配置啥东西,这是因为mybatis中有默认的实现,我们如果不配置,那么就默认使用那个默认的实现。在mybatis的核心包里有cache的接口和这个默认的实现,我截个图:
因此就明白了,不用配置也同样可以使用,mybatis中也就只实现了这一个默认实现类,如果不使用mybatis的默认二级缓存的话,就需要自己实现cache接口,然后再在mapper.xml中配置一下了,关于这个我在下面再谈,现在先把二级缓存用起来!
2.2 将po类实现Serializable接口
开启了二级缓存后,还需要将要缓存的pojo实现Serializable接口,为了将缓存数据取出执行反序列化操作,因为二级缓存数据存储介质多种多样,不一定只存在内存中,有可能存在硬盘中,如果我们要再取这个缓存的话,就需要反序列化了。所以建议mybatis中的pojo都去实现Serializable接口。下面以User为例截个图: