关于Mybatis的缓存机制

一、问题原因

这些天在与朋友编写业务逻辑的时候,发现了一个问题。当我们修改一个数据时,其他的数据也在跟着改变,研究了好久,才发现从地址上看,这些对象其实都是一个东西。但是他们都是从数据库中查询出来的,这个时候我们意识到Mybatis的缓存机制进行了一下简单的研究。

二、缓存分类

从网上我们了解到,Mybatis的缓存分为两层,一级缓存与二级缓存。

一次缓存是基于SqlSession的,在同一个SqlSession下,如果我们调用了相同的Sql语句,那么为了效率的提高,持久化层将会给我们返回一个相同的对象。他在配置中是默认打开的。

二级缓存我理解为一级缓存的拓展,对于Mybatis来说,二级缓存的开启可以使不同Namespace的缓存相互共通,使缓存适用于整个项目,而不是一个单独的Namespace,我了解到实现这种功能,还可以结合Redis或者ehcache诸如此类。他是默认关闭的。

 

三、一级缓存

由于一级缓存是默认打开的,所以我进一步的去做了几个小的实验,来看一看他的具体体现。

//生成SqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
//实例化接口
MyMapper myMapper = sqlSession.getMapper(MyMapper.class);
//一个简单的按照ID的Select方法
Student a = myMapper.getBean(1);
Student b = myMapper.getBean(1);

按照这样的查询,我们最终得出的结果是

从这张图我们可以看出,我们得出了两个相同的对象。这就是Mybatis的一级缓存机制。

那么有的时候缓存机制不是特别好用,例如当Spring整合Mybatis的时候

我们在这个时候,一般是@Autowired我们的Mybatis接口

在这个时候我们就算调用两次相同的查询,我们会发现结果也是两个不同的对象。

这个时候好像是缓存失效了一样。

在网上了解到,在整合的时候,每次查询都会生成一个新的SqlSession对象,查询开始生成,查询结束销毁。

这样会导致每次SqlSession都不同,这样也就引起了缓存失效

但是如果我们给业务逻辑增加了事务的话,例如

@Transactional (注解,开启事务)

这样的话作为事务,要保证所有的操作在一个SqlSession下,那么这样一级缓存就恢复了它的效果。

另外有一点需要注意,当我们调用新增,修改和删除的方法时,一级缓存防止脏读会被清除。

 

四、二级缓存

因为二级缓存需要主动开启,一般在项目中也会与Redis诸如此类进行结合。

由于在实际项目开发中遇到的并不多,所以我了解的也不是很全面。

自己理解上来讲,就是扩大了一级缓存的适用范围。

由于二级缓存是默认关闭的,如果想进行开启,需要如下几步

1、首先在Mybatis中配置全局缓存开始

<setting name="cacheEnabled" value="true"/>

2、其次在映射文件中开始缓存

<cache/>

而且在开发过程中,我经常使用注解的方式去做查询,所以对于二级缓存没有去进行试验,可能有一定的错误,欢迎指正。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章