缓存就是存在于内存中的临时数据
mysql数据库中的数据存在于表中即磁盘上。
查询--->程序IO读取磁盘的数据-
添加--->io向磁盘添加数据。
使用缓存的好处:减少和数据库的交互次数,提高执行效率。
1. 适合放入缓存中的数据: 经常查询并且不经常改变的;数据的正确与否对最终结果影响不大的;
2. 不适合放入缓存中的数据:经常改变的数据:数据的正确与否对最终结果影响很大的;数据安全性要求不高。
例如:商品的库存,银行的汇率,股市的牌价
Mybatis对缓存提供支持,一级缓存是默认使用的,二级缓存需要手动开启。
区别:
一级缓存的作用域是一个sqlsession内;
二级缓存作用域是针对mapper进行缓存;
一级缓存:
在参数和SQL完全一样的情况下,我们使用同一个SqlSession对象调用一个Mapper方法,往往只执行一次SQL,
因为使用SelSession第一次查询后,MyBatis会将其放在缓存中,以后再查询的时候,如果没有声明需要刷新,
并且缓存没有超时的情况下,SqlSession都会取出当前缓存的数据,而不会再次发送SQL到数据库。
一级缓存作用域是sqlsession级别的,同一个sqlsession中执行相同的sql查询(相同的sql和参数),第一次会去查询数据库并写到缓存中,第二次从一级缓存中取。
一级缓存是基于 PerpetualCache 的 HashMap 本地缓存,默认打开一级缓存。
参数不一致的时候
参数一致的时候
这里没有开启二级缓存 所以会执行两遍sql
二级缓存
基于SqlSessionFactory
二级缓存是namespace级别(一个mapper映射文件)的缓存(也就是在同一个mapper下都会生效),
需要我们手动开启和配置
注意:二级缓存只有在一级缓存死掉才可以执行
(1)开启二级缓存
<settings>
<!--开启二级缓存-->
<setting name="cacheEnabled" value="true"/>
</settings>
(2)在映射文件中使用缓存
<cache/>
(3)实体类序列化
使用相同的测试代码测试二级缓存
@Test
public void test03() throws Exception{
Reader rd = Resources.getResourceAsReader("conf.xml");
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(rd);
SqlSession session = factory.openSession();
StudentMapper sm = session.getMapper(StudentMapper.class);
Student stu1 = sm.selectByPrimaryKey(2);
System.out.println(stu1);
session.close();
//开启新的缓存 并没有完成一级缓存 还是执行了两个sql语句 因为session关闭了
SqlSession session2 = factory.openSession();
StudentMapper sm2 = session2.getMapper(StudentMapper.class);
Student stu2 = sm2.selectByPrimaryKey(2);
System.out.println(stu2);
}
执行顺序:二级缓存—>一级缓存------>数据库