首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

Java——Mybatis一级缓存

一、概述

当用户频繁查询某些固定的数据时,第一次将这些数据从数据库中查询出来,保存在缓存(内存,高速磁盘)中。当下次用户再次查询这些数据时,不用再通过数据库查询,而是去缓存里面查询。

这么做的目的,一是提升查询速度,二是降低数据库的并发请求压力。

在Mybatis中,缓存分为两种 : 一级缓存和二级缓存。而Mybatis默认开启一级缓存。

一级缓存是SqlSession级别的,二级缓存是Mapper级别的。

二、一级缓存

我们的请求都是由SqlSession来执行的,确切的说,应该是由DefaultSqlSession来执行的,更确切的说,其实是由DefaultSqlSession的Executor执行器来执行的。

一级缓存是针对每一个sqlSession进行缓存。每个sqlSession对象中使用HashMap存储一级缓存数据,key为hashcode+statementId+sql语句。Value为查询出来的结果集映射成的java对象。

不同的sqlSession中的缓存是互相不能读取的,即不共享。

三、生命周期

1.MyBatis在开启一个数据库会话时,会创建一个新的SqlSession对象,SqlSession对象持有一个Executor对象,

Executor对象持有一个PerpetualCache对象;

2.第一次查询先去缓存中找是否有缓存数据,发现没有,查询数据库,将查询到的数据写入sqlsession的一级缓存区域。

3.第二次查询先去缓存中找是否有缓存数据,发现有,直接从缓存区域中取出数据返回。

4.当会话结束时,SqlSession对象及其内部的Executor对象还有PerpetualCache对象也一并释放掉。

如果SqlSession调用了close()方法,会释放掉一级缓存PerpetualCache对象,一级缓存将不可用。

SqlSession中执行了任何一个update操作(update()、delete()、insert()) ,都会调用clearCache(),清空PerpetualCache对象中的数据,但是该对象仍可使用。(保证数据有效性)

四、存在问题

1.一级缓存并没有做粒度控制,而是在一次会话中对数据库中所有表的sql操作均做了缓存,这显然是不合理的。

2.任何更新(增、删、改)操作都会清除一级缓存,其实在有些情况下,这完全没有必要,比如两个完全不相关的表1和表2,如果你更新了表1,那为什么也要把表2的缓存也清除?

3.即便更新操作置空了当前SqlSession的一级缓存,也只是能够保证当前SqlSession的缓存失效,保证数据一致性,但是也不能保证其他SqlSession的缓存数据失效,这会导致数据不一致问题。

4.一级缓存只适用于单点,而不支持分布式部署。

5.而一级缓存的设计是每个sqlsession单独使用一个缓存空间,不同的sqlsession是不能互相访问数据的。当然,在sqlsession关闭后,其中数据自然被清空。

6.一般在mybatis集成spring时,会把SqlSessionFactory设置为单例注入到IOC容器中,不把sqlsession也设置为单例的原因是sqlsession是线程不安全的,所以不能为单例。那也就意味着其实是有关闭sqlsession的过程的。其实,对于每一个service中的sqlsession是不同的,这是通过mybatis-spring中的org.mybatis.spring.mapper.MapperScannerConfigurer创建sqlsession自动注入到service中的。

特此警告!!!!

当MyBatis与spring整合后,如果没有事务,一级缓存是失效的!一级缓存是失效的!一级缓存是失效的!

原因就是两者结合后,sqlsession如果发现当前没有事务,那么每执行一个mapper方法,sqlsession就被关闭了。如果需要维持一级缓存的可用性,有两种途径:

1.添加事务

2.使用二级缓存

综合以上一级缓存存在的问题,Mybatis设计开发了二级缓存。

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20190102G0KGO800?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券