mybatis缓存
一级缓存(默认开启)
1、介绍
一级缓存是SqlSession级别的缓存。在操作数据库时需要构造 sqlSession对象,在对象中有一个(内存区域)数据结构(HashMap)用于存储缓存数据。不同的sqlSession之间的缓存数据区域(HashMap)是互相不影响的。
2、缓存作用时机
2.1、使用缓存的时机
同一个session执行两次完全相同的sql语句,第一次查询结束会将查询得到的数据加载到该session的一级缓存中。当第二次查询的时候就会使用一级缓存而不会去数据库中再次查询。(注意:两次查询的返还结果为同一个对象,该返还结果的引用地址相同,如果改一个其他的属性也会变。例:第一次查询使用 Result result1,第二次查询使用Result result2,两者地址相同指向同一个Result在堆中的地址)
2.2、缓存失效
1)、每一个事务对应一个SqlSession,在Service事务结束的时候会关闭该SqlSession,也会导致清空当前一级缓存。(SqlSession的提交会导致当前事务(这个事务不是Service事务,是sql语句的事务)的提交。事务在Dao类上时,执行多次连接多次事务;事务加在Service类上是,执行多次连接一次事务;)
2)、SqlSession去执行commit操作(执行插入、更新、删除),清空SqlSession中的一级缓存,这样做的目的为了让缓存中存储的是最新的信息,避免脏读。
二级缓存
1、介绍
二级缓存是mapper级别的缓存,多个SqlSession去操作同一个Mapper的sql语句,多个SqlSession去操作数据库得到数据会存在二级缓存区域,多个SqlSession可以共用二级缓存,二级缓存是跨SqlSession的。
二级缓存是多个SqlSession共享的,其作用域是mapper的同一个namespace,不同的sqlSession两次执行相同namespace下的sql语句且向sql中传递参数也相同即最终执行相同的sql语句,第一次执行完毕会将数据库中查询的数据写到缓存(内存),第二次会从缓存中获取数据将不再从数据库查询,从而提高查询效率。Mybatis默认没有开启二级缓存需要在setting全局参数中配置开启二级缓存。
2、开启方法
-
MyBatis支持二级缓存的总开关:全局配置变量参数 cacheEnabled=true
-
该select语句所在的Mapper,配置了<cache> 或<cached-ref>节点,并且有效
-
该select语句的参数 useCache=true
3、缓存失效
-
SqlSession 在未提交的时候,SQL 语句产生的查询结果还没有放入二级缓存中,这个时候 SqlSession2 在查询的时候是感受不到二级缓存的存在的。
-
与一级缓存一样,SqlSession去执行commit操作(执行插入、更新、删除),会导致缓存失效。
-
如果涉及到链表查询(A,B两个表),更新、插入、删除的操作和查询的操作不在同一个Mapper文件中(即不在同一个namespace下,作用于不同的二级缓存空间),不会导致缓存失效(导致脏读,解决办法),相同会导致缓存失效。