MyBatis中默认SqlSession缓存开启
- 同一个SqlSession对象调用同一个select标签时,只有第一次访问数据库,第一季之后吧查询结果放到SqlSession缓存区(内存)中,但是,当中间数据库有变动时,缓存会消失
- 缓存的是statement对象(也就是select标签)
- 有效范围必须是同一个SqlSession对象
- 不同的SqlSession对象,只有在commit或者close之后,才放入缓存区
SqlSession session = factory.openSession();
SqlSession session1 = factory.openSession();
LogMapper mapper = session.getMapper(LogMapper.class);
LogMapper mapper1 = session1.getMapper(LogMapper.class);
List<Log> list2 = mapper.selAll();
session.commit();//或者session.close();
List<Log> list3 = mapper1.selAll();
session.close();
session1.close();
System.out.println(list2.size());
System.out.println(list3.size());
DEBUG 2018-09-24 07:33:05 第62行 Cache Hit Ratio [com.lee.mapper.LogMapper]: 0.0
DEBUG 2018-09-24 07:33:05 第139行 ==> Preparing: select * from log
DEBUG 2018-09-24 07:33:05 第139行 ==> Parameters:
DEBUG 2018-09-24 07:33:05 第139行 <== Total: 148
DEBUG 2018-09-24 07:33:05 第62行 Cache Hit Ratio [com.lee.mapper.LogMapper]: 0.5
148
148
如果去掉commit
List<Log> list2 = mapper.selAll();
List<Log> list3 = mapper1.selAll();
session.close();
session1.close();
System.out.println(list2.size());
System.out.println(list3.size());
会有两次
DEBUG 2018-09-24 07:40:42 第62行 Cache Hit Ratio [com.lee.mapper.LogMapper]: 0.0
DEBUG 2018-09-24 07:40:42 第139行 ==> Preparing: select * from log
DEBUG 2018-09-24 07:40:42 第139行 ==> Parameters:
DEBUG 2018-09-24 07:40:42 第139行 <== Total: 148
DEBUG 2018-09-24 07:40:42 第62行 Cache Hit Ratio [com.lee.mapper.LogMapper]: 0.0
DEBUG 2018-09-24 07:40:42 第139行 ==> Preparing: select * from log
DEBUG 2018-09-24 07:40:42 第139行 ==> Parameters:
DEBUG 2018-09-24 07:40:42 第139行 <== Total: 148
148
148
缓存流程
- 先去缓存区找是否有statement
- 如果有,则返回结果
- 如果没有,去数据库获取数据
- 数据库返回查询结果
- 吧查询结果放到对应的缓存区中
序列化与反序列化
序列化指将内存中的临时数据转变成硬盘中的永久数据
反序列化指将硬盘中的永久数据转为内存中的临时数据
SqlSessionFactory缓存
又叫二级缓存
有效范围:同一个factory内哪个SqlSession都可以获取
什么时候使用二级缓存:
-
当数据频繁被使用,很少被修改
使用二级缓存步骤 -
在mapper.xml中添加
-
如果不写readOnly="true"则需要将实体类序列化
<cache readOnly="true"></cache>
代码实现
InputStream is = Resources.getResourceAsStream("mybatis.xml");
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
SqlSession session = factory.openSession();
LogMapper mapper = session.getMapper(LogMapper.class);
List<Log> list2 = mapper.selAll();
List<Log> list3 = mapper.selAll();
System.out.println(list2.size());
System.out.println(list3.size());
session.commit();
session.close();
结果
DEBUG 2018-09-24 07:23:22 第62行 Cache Hit Ratio [com.lee.mapper.LogMapper]: 0.0
DEBUG 2018-09-24 07:23:23 第139行 ==> Preparing: select * from log
DEBUG 2018-09-24 07:23:23 第139行 ==> Parameters:
DEBUG 2018-09-24 07:23:23 第139行 <== Total: 148
DEBUG 2018-09-24 07:23:23 第62行 Cache Hit Ratio [com.lee.mapper.LogMapper]: 0.0
148
148
可见只有一次sql执行