MyBatis缓存

为什么使用缓存?

合理使用缓存是优化中最常见的,将从数据库中查询出来的数据放入缓存中,下次使用时不必从数据库查询,而是直接从缓存中读取,避免频繁操作数据库,减轻数据库的压力,同时提高系统性能。

MyBatis中缓存分类:

一级缓存(默认开启) 二级缓存(默认关闭

一级缓存:

        一级缓存是SqlSession级别的缓存。在操作数据库时需要构造sqlSession对象,在对象中有一个数据结构用于存储缓存数据(一级缓存就是一个Map)。不同的sqlSession之间的缓存数据区域是互相不影响的。也就是他只能作用在同一个sqlSession中,不同的sqlSession中的缓存是互相不能读取的。

        当用户发起查询请求查找某条数据时,sqlSession先去缓存中查找,是否有该数据,如果有,读取;如果没有,从数据库中查询,并将查询到的数据放入一级缓存区域,供下次查找使用。但sqlSession执行commit,即增删改操作时会清空缓存。这么做的目的是避免脏读。

既然有了一级缓存,那么为什么要提供二级缓存呢?

        二级缓存是mapper级别的缓存。多个SqlSession去操作同一个Mapper的sql语句,多个SqlSession可以共用二级缓存,二级缓存是跨SqlSession的。二级缓存的作用范围更大。

        还有一个原因,实际开发中,MyBatis通常和Spring进行整合开发。Spring将事务放到Service中管理,对于每一个service中的sqlsession是不同的,这是通过mybatis-spring中的org.mybatis.spring.mapper.MapperScannerConfigurer创建sqlsession自动注入到service中的。 每次查询之后都要进行关闭sqlSession,关闭之后数据被清空。所以spring整合之后,如果没有事务,一级缓存是没有意义的。那么如果开启二级缓存,关闭sqlsession后,会把该sqlsession一级缓存中的数据添加到namespace的二级缓存中。这样,缓存在sqlsession关闭之后依然存在。

开启二级缓存:

1、打开总开关,在MyBatis的配置文件中加入:

  
     
      
 

2、在需要开启二级缓存的mapper.xml中加入caceh标签

3、让使用二级缓存的POJO类实现Serializable接口

public class User implements Serializable {}

总结:

  1. 只要开启了二级缓存,在同一个Mapper文件下就有效。
  2. 所有的数据都会先放在一级缓存中,只有当会话提交,或者关闭的时候,才会提交到二级缓存中。
  3. 对于查询多commit少且用户对查询结果实时性要求不高,此时采用mybatis二级缓存技术降低数据库访问量,提高访问速度。
  4. 二级缓存是建立在同一个namespace下的,如果对表的操作查询可能有多个namespace,那么得到的数据就是错误的。

举个简单的例子:

订单和订单详情,orderMapper、orderDetailMapper。在查询订单详情时我们需要把订单信息也查询出来,那么这个订单详情的信息被二级缓存在orderDetailMapper的namespace中,这个时候有人要修改订单的基本信息,那就是在orderMapper的namespace下修改,他是不会影响到orderDetailMapper的缓存的,那么你再次查找订单详情时,拿到的是缓存的数据,这个数据其实已经是过时的。

根据以上,想要使用二级缓存时需要想好两个问题:

  1. 对该表的操作与查询都在同一个namespace下,其他的namespace如果有操作,就会发生数据的脏读。
  2. 对关联表的查询,关联的所有表的操作都必须在同一个namespace。

 

你可能感兴趣的:(java,MyBatis,缓存)