java的一级缓存的使用_MyBatis 一级缓存实现详解及使用注意事项

一级缓存介绍

在应用运行过程中,我们有可能在一次数据库会话中,执行多次查询条件完全相同的SQL,MyBatis提供了一级缓存的方案优化这部分场景,如果是相同的SQL语句,会优先命中一级缓存,避免直接对数据库进行查询,提高性能。具体执行过程如下图所示。

1650e88b1f67be7a740ba561d92c40bb.png

每个SqlSession回话中会创建Executor执行器,每个Executor执行器中有一个Local Cache。当用户发起查询时,MyBatis根据当前执行的语句生成MappedStatement,在Local Cache进行查询,如果缓存命中的话,直接返回结果给用户,如果缓存没有命中的话,查询数据库,结果写入Local Cache,最后返回结果给用户。

一级缓存配置

我们来看看如何使用MyBatis一级缓存。开发者只需在MyBatis的配置文件中,添加如下语句,就可以使用一级缓存。共有两个选项,SESSION或者STATEMENT,默认是SESSION级别,即在一个MyBatis会话中执行的所有语句,都会共享这一个缓存。一种是STATEMENT级别,可以理解为缓存只对当前执行的这一个Statement有效。

一级缓存实验

开启一级缓存,范围为会话级别,调用三次getStudentById,代码如下所示:

public void getStudentById() throws Exception {

SqlSession sqlSession = factory.openSession(true); // 自动提交事务

StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);

System.out.println(studentMapper.getStudentById(1)); // 查询数据库

System.out.println(studentMapper.getStudentById(1)); // 查询缓存

System.out.println(studentMapper.getStudentById(1)); // 查询缓存

}

public void addStudent() throws Exception {

SqlSession sqlSession = factory.openSession(true); // 自动提交事务

StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);

System.out.println(studentMapper.getStudentById(1)); // 查询数据库

System.out.println(studentMapper.addStudent(buildStudent())); // 更新数据

System.out.println(studentMapper.getStudentById(1)); // 查询数据库

sqlSession.close();

}

public void testLocalCacheScope() throws Exception {

SqlSession sqlSession1 = factory.openSession(true);

SqlSession sqlSession2 = factory.openSession(true);

StudentMapper studentMapper = sqlSession1.getMapper(StudentMapper.class);

StudentMapper studentMapper2 = sqlSession2.getMapper(StudentMapper.class);

System.out.println(studentMapper.getStudentById(1)); // 查询数据库

System.out.println(studentMapper.getStudentById(1)); // 查询缓存

System.out.println(studentMapper2.updateStudentName("小岑",1)); // 更新数据

System.out.println(studentMapper.getStudentById(1)); // 查询缓存,脏数据

System.out.println(studentMapper2.getStudentById(1)); // 查询数据库

}

一级缓存工作流程

一级缓存执行的时序图,如下图所示。

38f27a979684e29b5d14ac30b9c711f6.png

总结

MyBatis一级缓存的生命周期和SqlSession一致。

MyBatis一级缓存内部设计简单,只是一个没有容量限定的HashMap,在缓存的功能性上有所欠缺。

MyBatis的一级缓存最大范围是SqlSession内部,有多个SqlSession或者分布式的环境下,数据库写操作会引起脏数据,所以建议设定缓存级别为Statement。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值