关闭二级缓存_你不知道的Mybatis的一级、二级缓存

本文介绍了Mybatis的一级和二级缓存概念,包括缓存的作用、一级缓存依赖SqlSession、在不同事务场景下的行为,以及二级缓存的开启与配置。通过实例展示了缓存的工作原理,强调了缓存与事务的关系以及不同缓存层级的区别。
摘要由CSDN通过智能技术生成

Mybatis的一级、二级缓存

这也是一个面试大概率会问到的一个问题,一般简历上面都有写熟悉SQL优化什么的,不知道怎么优化的可以看下面这篇文章。而Mybaits作为大多数公司用的持久层框架,一级二级缓存概念也是经常被问到的,下面就结合概念和实战来写一下什么是Mybaits的一级、二级缓存!

1、什么是缓存?

什么是缓存:所谓的缓存,就是将程序或系统经常要调用的对象存在内存中,以便其使用时可以快速调用,不必再去创建新的重复的实例。

为什么使用缓存:使用缓存可以减少和数据库的交互次数,提高执行效率,并且可以保护数据库不被高并发的请求拖死。

什么样的数据能使用缓存,什么样的数据不能使用:

适用于缓存的数据:

  • 经常查询并且不经常被改变的数据。
  • 数据的正确与否对最终结果影响不大的数据。

不适用于缓存的数据:

  • 经常改变的数据。
  • 数据的正确与否对最终结果影响很大的。

2、Mybatis的一级缓存

Mybatis的一级缓存是默认开启的,其实指的是Mybaits中SqlSession对象的缓存。当我们执行查询之后,查询的结果会同时存入到 SqlSession为我们提供的一块区域中。该区域的结构是一个Map。当我们再次查询同样的数据,Mybatis会先去SqlSession中查询是否存在,存在的话直接返回,而不会再去数据库查询。这里要注意一个点,因为一级缓存是依赖于SqlSession对象的,当SqlSession对象消失时,Mybaits的一级缓存也就消失了。

当Mybaits与Spring整合的时候,不带Spring事务的方法内,每次请求数据库,都会新建一个SqlSession,这时候是使用不到一级缓存的,代码示例如下:

public void test1(){        MailConf mail1 = mailConfService.findByMailCode("11");        System.out.println(mail1);        MailConf mail2 = mailConfService.findByMailCode("11");        System.out.println(mail2);        System.out.println(mail1 == mail2);    }
21a8f00fd3cf5a2ac4b045a6a82046e1.png

image

如上图,可以看到,每次请求都新建了一个Sqlsession,返回的对象也不是同一个。

在带Spring事务的方法内,每次请求数据库,只新建一个SqlSession,这时候是可以使用到一级缓存的,代码示例如下:

@Transactional(rollbackFor = Exception.class)public void test1(){        MailConf mail1 = mailConfService.findByMailCode("11");        System.out.println(mail1);        MailConf mail2 = mailConfService.findByMailCode("11");        System.out.println(mail2);        System.out.println(mail1 == mail2);    }
be0c624843b335d25850adfb6ba57f00.png

如上图,这样就用到了一级缓存。

除了事务问题,还有一些问题也会影响到一级缓存,比如调用了Sqlsession的修改、添加、删除、commit()、close()等方法时,一级缓存也会被清空,这里就不一一示范了,底下示例就先删除一条记录,然后看下结果:

@Transactional(rollbackFor = Exception.class)    public void test1() {        MailConf mail1 = mailConfService.findByMailCode("11");        System.out.println(mail1);        // 删除        mailConfService.deleteConf(2);        MailConf mail2 = mailConfService.findByMailCode("11");        System.out.println(mail2);        System.out.println(mail1 == mail2);    }
2b98bc7adea8d091a5f7f6d7590fcf46.png

��同样的代码,不同的执行结果,这时候也是没有用到一级缓存。(这里有个小问题,如果把删除放在两次查询的最前面或者最后面,会不会用到缓存,可以自己测试一下。答案我先说下:只要不是放在两次查询的中间,都会使用到一级缓存。)

3、Mybatis的二级缓存

Mybatis的二级缓存是默认关闭的,它指的是Mybatis中SqlSessionFactory对象的缓存,由同一个SqlSessionFactory对象创建的SqlSession共享其二级缓存。这里注意:一个SqlSessionFactory对象可能创建多个SqlSession。

SpringBoot项目中二级缓存使用步骤:

  • 1、让当前的映射文件支持二级缓存(在xxx.xml中配置)
  • 2、让当前的操作支持二级缓存(在select标签中配置)

SqlSessionFactory和SqlSession关系图如下:

02619848c16c82fae2cc842e831469d2.png

代码示例如下:

6607d7ad00639894e2c9218b7297826e.png
@AutowiredSqlSessionFactory sqlSessionFactory;    public void test1() {        SqlSession sqlSession1 = sqlSessionFactory.openSession();        MailConfMapper mapper1 = sqlSession1.getMapper(MailConfMapper.class);        MailConf mailConf1 = mapper1.findByMailCode("11");        System.out.println(mailConf1);        // 关闭一级缓存        sqlSession1.close();        SqlSession sqlSession2 = sqlSessionFactory.openSession();        MailConfMapper mapper2 = sqlSession2.getMapper(MailConfMapper.class);        MailConf mailConf2 = mapper2.findByMailCode("11");        System.out.println(mailConf2);        // 关闭一级缓存        sqlSession2.close();        System.out.println(mailConf1 == mailConf2);    }
f893dbc7002dbe775c52649348c5e31e.png

上面代码,创建了两个SqlSession,并且关闭了SqlSession的一级缓存,然后结果图可以看到,只是查询了一次数据库。第二次返回的是缓存中的数据,但是看红色框那里,返回的对象竟然不是同一个,这是怎么回事呢?原因是这样的:SqlSession对象中存放的是返回数据的对象,而SqlSessionFactory对象中存放的是数据,不是对象,所以上面结果图看到的是返回数据是同一个,而对象却不是同一个。

总结

一级缓存与二级缓存的不同之处:

  • 1、Mybatis的一级缓存默认开启,而二级缓存默认关闭。
  • 2、Mybatis的一级缓存指的是Mybaits中SqlSession对象的缓存,而二级缓存指的是SqlSessionFactory对象的缓存。一个SqlSessionFactory对象包括多个SqlSession对象。
  • 3、SqlSession对象中存放的是返回数据的对象,而SqlSessionFactory对象中存放的是数据,不是对象。
  • 4、Mybatis和Spring整合的时候,一级缓存与事务有关,而二级缓存与事务无关。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值