缓存机制相关(持续新增)

一、Mybatis的二级缓存机制(处理循环引用问题)

1.1一级缓存(局部缓存 Local Cache------HashMap对象)

一级缓存默认开启且不能关闭,是SqlSession级别的缓存,在同个会话中,执行SQL后会将其存入缓存中,那自然下次再执行相同语句时,就从缓存中查询结果了。 一级缓存可以在配置文件设置禁用或者刷新缓存来控制其使用

设置禁用:进行全局设置(setting)将localCacheScope属性设置为STATEMENT,表示每次SQL语句后都清空缓存

SqlSession提供了clearCache()来清空一级缓存

设置刷新:手动刷新:调用SqlSession对象的clearCache()方法清空一级缓存【仅能清空当前SqlSession的缓存】

在程序使用SqlSession执行增、删、改等DML语句是,或者提交事物,关闭SqlSession时,SqlSession缓存的所有数据都会被清空

1.2一级缓存的底层实现原理

1.mybatis执行select查询语句时,MyBatis将根据该select语句、参数生产key

2.MyBatis判断在一级缓存(HashMap对象)中是否能找到对于的key

3.如果能找到,则称之为“命中缓存”,MyBatis直接从一级缓存中获取该key对于的values并返回

4.如果没有命中缓存,则连接数据库执行select语句,得到查询结果,将key和查询结果作为key-value对放入一级缓存

5.判断缓存级别是否为STATEMENT,如果时的话,则清空一级缓存

1.3一级缓存产生脏数据和避免方法

如果将localCacheScope设为SESSION(默认值),那么每次查询都会存到一级缓存,这样就带来了风险:如果程序对这些返回值所引用的进行了修改---实际上就是修改一级缓存的对象,将会影响SqlSession生命周期内通过缓存所返回的值,从而产生脏数据

所以,不要对MyBatis返回的对象进行修改:当SqlSession执行DMML语句时,自动flush刷新缓存,

1.4对于一级缓存的建议

        一级缓存是个粗粒度的缓存,没有缓存过期的概念,也没有容量的限定,因此不要让SqlSession长时间存活-------将SqlSession定义成局部变量,使用完之后立即关闭他

        一级缓存声明周期与SqlSession一致,意味着一级缓存不可能跨SqlSession产生作用,在实际开发过程中,可能存在多条并发线程使用不同的SqlSession访问数据,比如一条线程的SqlSession读取数据,一条线程的SqlSession修改数据,就可能会导致脏数据的产生。

使用一级缓存的的最佳实践(实时性较高的话,避免使用一级缓存)

  • 使用短生命周期的SqlSession
  • 避免使用SqlSession一级缓存

但是一级缓存默认开启并不可关闭,这里有两种处理方式

1.每个SqlSession永远只执行单词查询,执行第二次查询就再打开另外一个SqlSession

2.将localCacheStore设置成STATEMENT,这样可避免在SqlSession范围内使用一级缓存,但是依旧有脏数据产生的可能。

二、二级缓存(默认关闭)

二级缓存时是基于命名空间的缓存,可用跨会话,在多个会话之间共享缓存,可以减少数据库的访问次数,要使用二级缓存,需要在MyBtais的配置文件中配置相应的缓存实现类,并在需要使用缓存的Mapper接口上添加@CacheNamespace注解。

二级缓存的默认清除算法时LRU(最近最少使用的先被清除)

缓存刷新间隔时间,默认不用刷新

二级缓存开启后,同一个Mapper组建的多次查询语句相同并且参数相同时,只会执行一次-----后面将直接使用二级缓存查询数据。

二级缓存存在硬盘或者数据库中,因此被缓存的实体类应该实现Serializable接口,这样才能方便缓存机制将其序列化。

在代码中开启二级缓存,首先要将SqlSession关闭或者提交,这样才可以将数据写入二级缓存,并关闭一级缓存。

2.1二级缓存的问题

在不同Mapper之间并发访问时统一可能导致脏数据的产生

假设有PersonMapper里面有id=1的Person对象,关联的有id=2的Address对象

这时切换线程,使用AddressMapper修改Address对象中id=2的参数

这是切换回原线程,访问数据id=1的对象,在访问关联的id=2的对象,这时显示的还是修改前的数据

建议:有多表查询的场景,尽量不要用二级缓存

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值