MyBatis进阶三:Mybatis缓存;(包括一级缓存和二级缓存)

 Mybatis缓存。

注:在实际中一二级缓存的使用习惯和普遍采用的策略,这个需要慢慢积累~~~

目录

0.什么是缓存,为什么要引入缓存: 

1.Mybatis中的缓存简介:

(1)一级缓存和二级缓存简介

(2)缓存的范围

(3)在编码中如何使用二级缓存,二级缓存的规则

2.案例演示

(1)案例1:一级缓存

当然,第一次查询的时候,是会执行SQL语句,从数据库去提取结果的;

但是,第二次查询相同的数据的时候,第二次就会从本sqlSession的一级缓存中去提取数据了;

不同的sqlSession之间,其缓存的对象只对自己available

sqlSession执行commit之后,会清空一级缓存

(2)案例2:二级缓存(重点内容)

首先,二级缓存初体验,开启二级缓存

catch 标签的四个属性(重点内容)

SQL语句标签上的属性 


0.什么是缓存,为什么要引入缓存: 

什么是缓存:缓存是缓冲存储的意思,是Mybatis中用于数据优化,提高程序执行效率的有效方式。

比如,第一次查询时获取到了【“婴幼儿奶粉”这条数据】,紧接着因为程序的需要,还需要重新的获取一次【“婴幼儿奶粉”这条数据】;

如果没有缓存:其需要再次从数据库中把【“婴幼儿奶粉”这条数据】提取出来;但是,要知道MySQL的数据是存储在硬盘上的,硬盘的读写速度很慢;而且,上面两次获取的都是【“婴幼儿奶粉”这条数据】;

为了优化:引入缓存,把第一次查询时获取到的【“婴幼儿奶粉”这条数据】放在某个内存的区域中,当再次需要获取【“婴幼儿奶粉”这条数据】的时候,不去读取数据库了,而是直接从内存中提取【“婴幼儿奶粉”这条数据】;内存的读取速度比硬盘快几十倍。


 

1.Mybatis中的缓存简介:

(1)一级缓存和二级缓存简介

(1)一级缓存:是Mybatis默认开启的,其数据对象存储的范围是SqlSession这个级别,即在同一个SqlSession处理的过程中,对同一个数据进行反复提取时,其就会利用到缓存机制,来提高程序的处理速度。

(2)二级缓存:没有默认开启,需要手动开启,其存储的范围是Mapper NameSpace。即,其范围是Mapper映射器的某个命名空间;

(注:这个范围很容易理解了,就是可访问的方位,或者数available的范围)

……………………………………………………

(2)缓存的范围

(1)存储对象:上图,比如当前程序有两个命名空间,当调用Mapper XML文件中某个命名空间(比如goods这个命名空间爱你)的SQL语句后,查询到的【“婴幼儿奶粉”这条数据】这条数据在实际存储的时候是以对象的形式存储的,而这个对象可以认为是“隶属于”该命名空间(比如goods这个命名空间)的,这个对象是被存储到了JVM内存的。。同时,Mybatis中存储对象,其本质是使用Map这种数据结构来保存的。

(2)SqlSession范围的:一级缓存:比如实际中,有3个用户,每一个用户都需要创建他自己的SqlSession会话对象;默认情况下SqlSession的一级缓存是开启的,在SqlSession中进行的数据查询工作得到的数据对象都会保存下来;;;但是在某个SqlSession中得到的任何查询结果对象,其默认的生存周期都是仅限于当前的SqlSession对象中;;;;即,每一个用户所得到的一级缓存,其只对自己有效,而且,当用户的SqlSession对象被释放的时候,存储在里面的缓存对象都会被清空。   

         一般,某个用户为了访问数据库,其会建立一个SqlSession对象,通常用户在进行完某一个操作后,其马上会把这个SqlSession释放掉,,,这也意味着,存储在SqlSession的一级缓存重复使用率不高,同时也可能会浪费额外的内存空间。

(3)NameSpace命名空间的:二级缓存:为了解决一级缓存的问题,引入了二级缓存。

范围隶属于goods这个命名空间的缓存对象,会被所有同命名空间中的所有的SqlSession共享。。。。(待验证问题:同一个SqlSession也可能会调用不同命名空间中的SQL哎~~~)。。。。即,他的意思是,比如SqlSession1调用了goods命名空间中的某条SQL,获取到了【“婴幼儿奶粉”这条数据】。。。。当SqlSession2还调用goods命名空间中的那条SQL,想获取【“婴幼儿奶粉”这条数据】的时候,二级缓存就起作用了。

……………………………………………………

(3)在编码中如何使用二级缓存,二级缓存的规则

(1)所有的二级缓存,默认都会为当前命名空间中的查询操作,提供缓存;而,二级缓存的开启需要在Mapper XML中进行简要配置;

(2)这么做的目的是:保证数据的一致性。设想,A用户进行写操作后(PS:由于事务的关系,写操作如果想影响到数据库需要commit啦),这个写操作已经修改了某条数据,,如果不清空缓存,当B用户来查询该条数据的时候,如果其还是从缓存中获取,(但实际上,这条数据已经被修改了),这样B用户得到的数据和数据库底层存储的就不一致了。。。。。。所以,在任何用户在commit后,都会把该NameSpace下的所有的缓存都强制清空,这样以后,后面再获取数据都需要从数据库中读取数据了,(保证数据的一致)。

说明一个问题:只有查询操作的SqlSession在commit的时候是不会清空二级缓存的,但是会清空一级缓存。● SqlSession执行更新操作(update、delete、insert)后并执行SqlSession.commit()时,不仅清空其自身的一级缓存(执行更新操作的结果),也清空二级缓存。● 但是在查询时,commit是不会清除二级缓存的,所以这里没有效果由于查询操作其实并不会改变数据,因此对数据没有影响。所以我们通常会说commit之后会将二级缓存也清空。

(3)可以设置某条SQL不使用缓存。(即,调用该SQL产生的结果对象不存储到缓存空间中吧)只需要在该SQL所在的<select>标签中,设置useCache=false;

(4)如果给某条SQL所在的<select>标签,设置flushCache=true,则表示在调用这条SQL以后,清空该NameSpace下的缓存。


 

2.案例演示

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值