码迷,mamicode.com
首页 > 其他好文 > 详细

0054、mybatis缓存学习总结

时间:2020-07-03 19:53:44      阅读:93      评论:0      收藏:0      [点我收藏+]

标签:tor   使用   不能   and   span   客户   red   二级缓存   幻读   

1、  mybati默认开启一级缓存(同一个session内缓存)

2、  mybatis一级缓存命中原则(一级缓存指的是同一个sqlsession内)

1)       StatementId必须相同(即xml中的<select id=””>中的id需相同)

2)       查询参数必须相同(传递给sql语句中的有用的参数必须相同,比如sql语句中用id做为查询条件,用map传递参数的时候,两次查询时,map中都放了id=1,即使两次map额外放了没用的name=”zhangsan”和name=”lisi”也是能够命中缓存的,因为map中多放的name是不会做为sql中的查询条件的,而sql中的查询条件id的值相同就能命中)

3)       分页参数必须相同

4)       传递给jdbc的sql语句必须相同,比如第一次查询传递的是select * from emp where id=1,第二次查询传递的是select * from emp where 1=1 and id=1,虽然从查询结果上来看,得到的结果是相同的,但是由于两次传递的sql不相同,所以无法命中缓存

5)       环境必须相同(比如连接数据的环境一次是开发环境,一次是测试环境,肯定不能命中缓存)

 

3、mybatis一级缓存的生命周期

         mybatis一级缓存是什么时候产生的?什么时候销毁的?

mybatis只有在调用SqlSession的select的相关方法时才会产生缓存,举例:xml中定义一个<select>标签里边写好select语句,但是在.java类中通过SqlSession的update方法来调用该select语句,首先mybatis是不会报错的,是能够成功查询的,其次就是说update方法虽然调用的是select语句,但是由于是update方法,所以不会产生缓存。

一级缓存失效的几种情况:

1)  session关闭,一级缓存销毁(可打断点看sqlSession里边的缓存的存放位置,然后通过反射机制取到存放缓存的map,分别在session关闭前后输出map中的内容,确定session关闭,缓存被清空)

2)  执行commit

3)  执行rollback

4)  执行update(包含insert、update、delete,与表无关:查询A表,更新B表,也会导致查询A表的缓存失效)

5)调用SqlSession.clearCache()方法手动清除一级缓存

 

数据库的事物隔离级别可能会导致脏读,不可重复读、幻读等问题,mybatis的一级缓存帮助mysql数据库解决了以上问题,相当于优化了mysql数据库的事物隔离级别

 

idea中调用某个接口的方法时,想看其实现类的方法,但是无法进入到实现类,可以打断点,看取得的该接口的值具体是哪个实现类,然后进入到该实现类,搜索对应的调用的方法,就可以看到实现类中是如何实现该方法的了。

 

4、spring整合mybatis的情况下mybatis的一级缓存是什么样的呢?

1)  方法上加了事物,两次查询用的是一个sqlsession,所以第二次查询的时候可以命中缓存

2)  方法上没有加事物,则每次查询,spring都会关闭旧的sqlsession,创建一个新的sqlsession,所以没有加事物的方法,是无法命中mybatis的一级缓存的。

 

                               mybatis二级缓存

二级缓存是两个不同的sqlsession

1、  如何开启二级缓存

1)  MyBatis.xml中增加配置

<settings>  

            <setting name=”cacheEnabled” value=”true”/>

</settings>

2)  mapper.xml中增加cache标签

<cache/>

3)  entity实现Serializable接口

2、  mybatis二级缓存的命中原则

结论:前提是同一个SqlSessionFactory内,与一级缓存的命中原则相同,但是不能跨越SqlSessionFactory(如何解决跨越SqlSessionFactory的问题呢?mybatis和redis整合,将缓存的内容不再保存在jvm中,而是保存在redis中,这样就解决了跨SqlSessionFactory的问题)

3、  mybatis二级缓存生命周期

mybatis二级缓存产生的条件:

1)  要满足一级缓存的产生条件

2)  Close Session 或者Commit session

mybatis二级缓存销毁的条件:

1)  以mapper.xml文件为单位,执行一个mapper.xml文件中的update语句,会销毁该mapper.xml中的查询语句所产生的二级缓存(对比:一级缓存是以sqlsession为单位进行销毁的)

注意:rollback和clearCache方法既不会影响二级缓存的创建,也不会影响到二级缓存的销毁

 

4、  eviction清除策略

1)  LRU最近最少使用:移除最长时间不被使用的对象-->LinkedHashMap

2)  FIFO先进先出:按对象进入缓存的时间来移除它们-->LinkedList

3)  SOFT软引用:基于GC和软引用规则移除对象-->SoftReference

4)  WEAK若引用:基于GC和弱引用规则移除对象-->WeakReference

缓存引用的最大数目,默认是1024,当缓存引用达到最大数目时,按照eviction设定的策略清除缓存对象

如何设定移除策略和最大缓存数呢?

还是在mapper.xml文件重点<cache/>标签中进行设定,如下:

<cache eviction=”FIFO” size=”2”/>

即二级缓存只能缓存两个实例

 

客户端查询数据的过程:

client->二级缓存->一级缓存->数据库

 

使用建议:

一级缓存:放心大胆的用,但是没什么卵用

二级缓存:小心谨慎使用,或者不用

 

0054、mybatis缓存学习总结

标签:tor   使用   不能   and   span   客户   red   二级缓存   幻读   

原文地址:https://www.cnblogs.com/xiao1572662/p/13231771.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!