Mybatis的一级缓存、二级缓存

为什么要用缓存?

将数据存放在程序内存(缓存)中,用于减轻数据查询的压力,提升读取数据的速度,提高性能。

一级缓存

Mybatis一级缓存实际上就是一个依赖于SqlSession的缓存对象。
具体来说就是将查询到的结果以Map(K,V)的形式存在于缓存区中。


public class PerpetualCache implements Cache {

	  private final String id;
  
	  private Map<Object, Object> cache = new HashMap<Object, Object>();
  }

一级缓存默认开启状态。
举例:

  @Test
    void select(){     
        Start st=t.selectById(1); 
        System.out.println("第一次查询:");       
        System.out.println(st);
        
        Start s=t.selectById(1);        
        System.out.println("第二次查询:");
        System.out.println(s);
    }
第一次查询:
17:21:32.483 [main] DEBUG com.example.mytest01.dao.t_tempDao.selectById - ==>  Preparing: select * from t_emp where username=? 
17:21:32.605 [main] DEBUG com.example.mytest01.dao.t_tempDao.selectById - ==> Parameters: 1(Integer)
17:21:32.695 [main] DEBUG com.example.mytest01.dao.t_tempDao.selectById - <==      Total: 1
com.sun.proxy.$Proxy80
Start{username='01', name='123', password='1234', sex='男', birthday='2004-02-01', hire_date='2000-03-05', position='主管', qualification='本科', experience='null', currentPage=0, flag='2', super_id='null'}
第二次查询:
com.sun.proxy.$Proxy80
Start{username='01', name='123', password='1234', sex='男', birthday='2004-02-01', hire_date='2000-03-05', position='主管', qualification='本科', experience='null', currentPage=0, flag='2', super_id='null'}

注意:

如果SqlSession调用了close()方法,会释放掉一级缓存PerpetualCache对象,一级缓存将不可用;
如果SqlSession调用了clearCache(),会清空PerpetualCache对象中的数据,但是该对象仍可使用;
SqlSession中执行了任何一个update操作(update()、delete()、insert()) ,都会清空PerpetualCache对象的数据,但是该对象可以继续使用

二级缓存

二级缓存,数据仍是以Map集合形式保存。
二级缓存的生命周期是整个应用的周期。

二级缓存开启条件

1.实体类需要实现序列化接口Serializable
2.打开二级缓存的开关

  • 总开关(mybatis.xml中需要设置cacheEnable值为true)
  • 局部开关(mapper.xml中需要设置<case/>标签)
  • 细节开关——针对某一个方法(查询标签中的useCase属性,默认为false)

当开启二级缓存后,数据的查询执行的流程就是二级缓存-> 一级缓存 -> 数据库

在这里插入图片描述

@Test
void select(){

    System.out.println("第一次查询:");
    Start st=t.selectById(1);
    System.out.println(st);
    
    System.out.println("第二次查询:");
    Start s=t.selectById(1);
    System.out.println(s);
}
第一次查询:
22:50:28.141 [main] DEBUG com.example.mytest01.dao.t_tempDao - Cache Hit Ratio [com.example.mytest01.dao.t_tempDao]: 0.0
22:50:29.187 [main] DEBUG com.example.mytest01.dao.t_tempDao.selectById - ==>  Preparing: select * from t_emp where username=? 
22:50:29.222 [main] DEBUG com.example.mytest01.dao.t_tempDao.selectById - ==> Parameters: 1(Integer)
22:50:29.247 [main] DEBUG com.example.mytest01.dao.t_tempDao.selectById - <==      Total: 1
Start{username='01', name='123', password='1234', sex='男', birthday='2004-02-01', hire_date='2000-03-05', position='主管', qualification='本科', experience='null', currentPage=0, flag='2', super_id='null'}
第二次查询:
22:50:29.402 [main] DEBUG com.example.mytest01.dao.t_tempDao - Cache Hit Ratio [com.example.mytest01.dao.t_tempDao]: 0.5
Start{username='01', name='123', password='1234', sex='男', birthday='2004-02-01', hire_date='2000-03-05', position='主管', qualification='本科', experience='null', currentPage=0, flag='2', super_id='null'}

第一次查询时,会从缓存区中进行查找,由于缓存区没有,命中率为零。
第二次查询时,从缓存区中查找到值,命中率变为50%。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值