mybatis提供了缓存机制减轻数据库压力,提升数据库性能
mybatis的缓存分为两级:一级缓存、二级缓存
一级缓存是SqlSession级别的缓存,缓存的数据只在SqlSession内有效
二级缓存是mapper级别的缓存,同一个namespace公用这一个缓存,因此对SqlSession是共享的
一级缓存:
mybatis的一级缓存是SqlSession级别的缓存,在操做数据库的时候须要先建立SqlSession会话对象,在对象中有一个HashMap用于存储缓存数据,此HashMap是当前会话对象私有的,别的SqlSession会话对象没法访问。
具体流程:
1.第一次执行select完毕会将查到的数据写入SqlSession内的HashMap中缓存起来
2.第二次执行select会从缓存中查数据,若是select相同且传参数同样,那么就能从缓存中返回数据,不用去数据库了,从而提升了效率
注意事项:
1.若是SqlSession执行了DML操做(insert、update、delete),并commit了,那么mybatis就会清空当前SqlSession缓存中的全部缓存数据,这样能够保证缓存中的存的数据永远和数据库中一致,避免出现脏读
2.当一个SqlSession结束后那么他里面的一级缓存也就不存在了,mybatis默认是开启一级缓存,不须要配置
3.mybatis的缓存是基于[namespace:sql语句:参数]来进行缓存的,意思就是,SqlSession的HashMap存储缓存数据时,是使用[namespace:sql:参数]做为key,查询返回的语句做为value保存的。
二级缓存:
二级缓存是mapper级别的缓存,也就是同一个namespace的mapper.xml,当多个SqlSession使用同一个Mapper操做数据库的时候,获得的数据会缓存在同一个二级缓存区域
二级缓存默认是没有开启的。须要在setting全局参数中配置开启二级缓存
mybatis-config.xml:
<setting name="cacheEnabled" value="true"/>
默认是 false:关闭
在userMapper.xml中配置:
<cache />当前mapper下全部语句开启二级缓存
若想禁用当前select语句的二级缓存,添加useCache="false"修改以下:
<select id="getCountByName" parameterType="java.util.Map" resultType="INTEGER" statementType="CALLABLE" useCache="false">
具体流程:
1.当一个sqlseesion执行了一次select后,在关闭此session的时候,会将查询结果缓存到二级缓存
2.当另外一个sqlsession执行select时,首先会在他本身的一级缓存中找,若是没找到,就回去二级缓存中找,找到了就返回,就不用去数据库了,从而减小了数据库压力提升了性能
注意事项:
1.若是SqlSession执行了DML操做(insert、update、delete),并commit了,那么mybatis就会清空当前mapper缓存中的全部缓存数据,这样能够保证缓存中的存的数据永远和数据库中一致,避免出现脏读
2.mybatis的缓存是基于[namespace:sql语句:参数]来进行缓存的,意思就是,SqlSession的HashMap存储缓存数据时,是使用[namespace:sql:参数]做为key,查询返回的语句做为value保存的。
3.实体类对象必需要实现序列化接口
查找规则:
一、先判断二级缓存是否开启,若是没开启,再判断一级缓存是否开启,若是没开启,直接查数据库
二、若是一级缓存关闭,即便二级缓存开启也没有数据,由于二级缓存的数据从一级缓存获取
三、通常不会关闭一级缓存
四、二级缓存默认不开启
五、若是二级缓存关闭,直接判断一级缓存是否有数据,若是没有就查数据库
六、若是二级缓存开启,先判断二级缓存有没有数据,若是有就直接返回;若是没有,就查询一级缓存,若是有就返回,没有就查询数据库;
/*一级缓存(sqlsession级别的缓存,默认开启):
* 同一个sqlsession执行相同的sql语句,第二次直接从缓存获取
* 二级缓存(mapper基本的缓存,默认关闭,基本上不用,实际中也不怎么用):
* 不一样的sqlsession执行一样的sql语句也会缓存
*
* 开启二级缓存步骤:
* 1.设置settings,<setting name="cacheEnabled" value="true"/>
* 2.在mapper文件里面配置缓存的属性
* <cache/>
* 3.测试
*
* 注意点:二级缓存是将整个对象以流的形式保存到缓存,全部须要序列化对象,须要让实体类序列化
*
* */