在操作系统和Mybaits都有一级缓存和二级缓存的概念,而它们两个的含义却大有不同,当我在第一次接触mybaits中的cache就不由的联系到操作系统的cache,今天将他们做简单的区分。
在操作系统中CPU速度比主存(内存)速度快很多,CPU存取快而内存存取慢就导致了CPU要等待内存,白白浪费了CPU的时间,人们为了解决这样的问题引入了cache(高速缓冲存储器)作为CPU和内存的”桥梁“,它比CPU略慢又比内存要快。
操作系统中cache又包含为一级缓存和二级缓存(有些有三级缓存,或者只有二级缓存和三级缓存)一级缓存速度快容量小,二级缓存速度较慢容量较大
下面来说说Mybaits中一级缓存和二级缓存:
大多数持久层框架也有一级缓存和二级缓存的概念,mybatis一样存在一级缓存和二级缓存,他们也都是cache。
什么是mybatis中缓存(cache)?
数据交换的缓冲区,当应用程序需要读取数据时,先从数据库中将数据取出,放置在缓冲
区中,应用程序从缓冲区可以多次快速读取数据,不用每次去数据库中查找;
在mybatis一级缓存是基于PerpetualCache
(MyBatis自带)的HashMap本地缓存,它的范围是SqlSession,而一级缓存是默认开启的。当进行数据的增删改时会清除之前存在SqlSession的缓存,或者sqlsession
flush
(刷新)又或者 close
(关闭)之后,该 sqlsession
中所有的 cache
(缓存)也会被清空。
那么默认开启后怎么使用呢?
在进行同样的select并且没有进行上述清空一级缓存的操作,就会用到一级缓存---MyBatis
会将其放在一级缓存中,再次查询时SqlSession
取出当前缓存的数据,而不会再次发送 SQL
到数据库。
二级缓存是全局缓存可以被所有SqlSession
共享,作用在SqlSessionFactory。
二级缓存与一级缓存原理相同,默认也是采用 PerpetualCache
,使用HashMap
作为存储,不同在于其存储作用域为Mapper
( Namespace
)范围,并且可自定义存储源,例如Ehcache
等第三方中间件。作用域为 namespance
是指对该 namespance
对应的配置文件中所有的 select
操作结果都缓存,这样不同线程之间就可以共用二级缓存。
而且二级缓存是需要手动开启的,开启方法如下:
1.mybatis-config.xml
的 settings
元素中写入以下代码(二级缓存的总开关)
2.在mapper.xml中mapper 标签后写入二级缓存的配置
eviction:代表的是缓存回收策略,MyBatis中有四种策略
flushInterval:刷新时间,单位是毫秒,时间过后二级缓存中的数据被清空
size:引用数目,正整数,代表缓存最多可以存储多少个对象,不宜设置过大。因为一级缓存在内存中保存设置过大有可能会导致内存溢出。
readOnly:只读,缓存中的数据不能修改
3.也可以单独设置某个SELECT语句是否要开启二级缓存
那么二级缓存开启后在什么情况下会运用呢?
1.在一个sqlseesion执行了一次SELECT并且关闭了sqlseesion时会将查询结果缓存到二级缓存中去
2.另一个sqlseesion执行SELECT时首先会在一级缓存中找,如果没有找到,就会去二级缓存中找,如果找到就取出,不再去数据库进行SELECT,从而减少了数据库的压力提高了性能
通过上述可以系统的将Mybaits中一级缓存和二级的不同点阐述总结:
1:一级缓存默认自动开启。二级缓存需要手动开启
2:一级缓存作用范围是sqlseesion。二级作用范围是SqlSessionFactory
3:一级缓存有生命周期,从一个新的select语句开始存入一级缓存到进行增删改等操作清空缓存结束一个完整生命周期。
4:一级缓存保存在内存当中。二级缓存可以自定义存储源也可以将数据序列化后放入磁盘中。
关于mybaits缓存的补充:mybaits二级缓存因为是定时清空的所以有可能读脏数据,使用的条件比较苛刻,现实应用场景已经十分少见,特别是分布式环境极大可能读取到错误的数据。可以引用redis等第三方内存库作为mybatis的缓存。