缓存

本文详细介绍了MyBatis的缓存机制,包括默认SqlSession缓存的开启,缓存流程,序列化与反序列化的过程,以及SqlSessionFactory的二级缓存。在同一个SqlSession中,缓存会存储第一次查询的结果,避免重复查询数据库。当数据不常修改且需要频繁使用时,可以启用二级缓存,提高效率。实现二级缓存需要在mapper.xml中配置,并确保实体类可序列化。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

MyBatis中默认SqlSession缓存开启

  1. 同一个SqlSession对象调用同一个select标签时,只有第一次访问数据库,第一季之后吧查询结果放到SqlSession缓存区(内存)中,但是,当中间数据库有变动时,缓存会消失
  2. 缓存的是statement对象(也就是select标签)
  3. 有效范围必须是同一个SqlSession对象
  4. 不同的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

缓存流程

  1. 先去缓存区找是否有statement
  2. 如果有,则返回结果
  3. 如果没有,去数据库获取数据
  4. 数据库返回查询结果
  5. 吧查询结果放到对应的缓存区中

在这里插入图片描述

序列化与反序列化

序列化指将内存中的临时数据转变成硬盘中的永久数据
反序列化指将硬盘中的永久数据转为内存中的临时数据

SqlSessionFactory缓存

又叫二级缓存
有效范围:同一个factory内哪个SqlSession都可以获取
什么时候使用二级缓存:

  1. 当数据频繁被使用,很少被修改
    使用二级缓存步骤

  2. 在mapper.xml中添加

  3. 如果不写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执行

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值