MyBatis一级缓存避坑完全指南

 更新时间:2018年11月28日 11:53:04   作者:justmehyp  
这篇文章主要给大家介绍了关于MyBatis一级缓存避坑的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

一级缓存概念
当我们使用Mybatis进行数据库的操作时候,会创建一个SqlSession来进行一次数据库的会话,会话结束则关闭SqlSession对象。那么一个SqlSession的生命周期即对应于Mybatis的一次会话。在Mybatis的一次会话中,我们很有可能多次查询完全相同的sql语句,如果不采取措施的话,每一次查询都查询一次数据库。而一次会话时间一般都是极短的,相同Sql的查询结果极有可能完全相同。由于查询数据库代价是比较大的,这会导致系统的资源浪费。

为了解决这个问题,Mybatis对每一次会话都添加了缓存操作。这个缓存的作用域为一次会话中。缓存随着会话(SqlSession)的创建而产生,随着会话结束而释放。对一次会话的查询操作,总是先查看缓存中是否存在查询结果,如果存在则直接取缓存中的结果,不存在则查询数据库。这样的话,一次会话中的完全相同的查询则只会查询一次,节省了系统资源。

引言

MyBatis 一级缓存(MyBaits 称其为 Local Cache)无法关闭,但是有两种级别可选:

package org.apache.ibatis.session;

/**
 * @author Eduardo Macarron
 */
public enum LocalCacheScope {
 SESSION, //session 级别的缓存 STATEMENT //statement 级别的缓存
}

1)session 级别的缓存

在同一个 sqlSession 内,对同样的查询将不再查询数据库,直接从缓存中。

验证代码:

[

public static void main(String[] args) throws IOException { InputStream inputStream = new ClassPathResource("mybatis.xml").getInputStream(); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); SqlSession sqlSession = sqlSessionFactory.openSession(); UserDao mapper = sqlSession.getMapper(UserDao.class); System.out.println(mapper.get(1L)); System.out.println("-------------------"); System.out.println(mapper.get(1L));}

输出:

日志输出可以看到,第一次查询通过数据库查询,第二次则没有,直接通过缓存读取。

坑:这种缓存策略有一个坑,在服务集群时就会出现问题。

假设现在有一个服务集群,有两个节点。

首先,两个节点都进行了同样的查询,两个节点都有自己的一级缓存,后续同样的查询,两个节点将不再查询数据库。

如果此时节点 1 执行了 update 语句,那么节点 1 的一级缓存会被刷新,而节点 2 的一级缓存不会改变。

2)statement 级别的缓存

避坑: 为了避免这个问题,可以将一级缓存的级别设为 statement 级别的,这样每次查询结束都会清掉一级缓存。MyBatis 源码如下:

在 MyBatis 的配置文件中,添加以下配置:

验证代码和上面的一样不变。

输出:

可以看到,即使是同样的查询,每次查询都是直接读取数据库了。

避坑完毕。

缓存是不可能不要缓存的,这个时候,就需要使用缓存中间件了,由缓存中间件管理缓存。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对脚本之家的支持。

相关文章

  • java线程池使用及原理面试题

    java线程池使用及原理面试题

    很多面试官喜欢把线程池作为问题的起点,然后延伸到其它内容,由于我们专栏已经说过队列、线程、锁面试题了,所以本章面试题还是以线程池为主
    2022-03-03
  • 使用SpringBoot与EasyExcel实现复杂的导入导出

    使用SpringBoot与EasyExcel实现复杂的导入导出

    这篇文章主要介绍了使用SpringBoot与EasyExcel实现复杂的导入导出,EasyExcel是一个快速解决大文件内存溢出的Excel处理工具,它能让你在不用考虑性能、内存等因素的情况下,快速完成Excel的读、写等功能,需要的朋友可以参考下
    2023-10-10
  • Springboot自定义mybatis拦截器实现扩展

    Springboot自定义mybatis拦截器实现扩展

    本文主要介绍了Springboot自定义mybatis拦截器实现扩展,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-12-12
  • java实现excel导出合并单元格的步骤详解

    java实现excel导出合并单元格的步骤详解

    这篇文章主要介绍了java实现excel导出合并单元格,通过使用Apache POI库,我们可以方便地创建Excel文件、填充数据、合并单元格和导出Excel文件,需要的朋友可以参考下
    2023-04-04
  • 详解Java异常处理的使用与思考

    详解Java异常处理的使用与思考

    异常处理的概念起源于早期的编程语言,如 LISP、PL/I 和 CLU。这些编程语言首次引入了异常处理机制,以便在程序执行过程中检测和处理错误情况。本文主要来介绍一下Java中的异常处理,需要的可以参考一下
    2023-04-04
  • 教你如何监控 Java 线程池运行状态的操作(必看)

    教你如何监控 Java 线程池运行状态的操作(必看)

    这篇文章主要介绍了教你如何监控 Java 线程池运行状态的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-02-02
  • Java分支结构程序设计实例详解

    Java分支结构程序设计实例详解

    这篇文章主要介绍了Java分支结构程序设计例题,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-01-01
  • SpringBoot开启异步调用方法

    SpringBoot开启异步调用方法

    这篇文章主要为大家详细介绍了SpringBoot开启异步调用方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-09-09
  • Java中获取 List中最后一个元素3种方法以及实际应用

    Java中获取 List中最后一个元素3种方法以及实际应用

    这篇文章主要给大家介绍了关于Java中获取 List中最后一个元素3种方法以及实际应用的相关资料,由于List的索引是从0开始的,所以最后一个元素的索引是List的大小减1,需要的朋友可以参考下
    2023-11-11
  • pagehelper插件显示total为-1或1的问题

    pagehelper插件显示total为-1或1的问题

    这篇文章主要介绍了pagehelper插件显示total为-1或1,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-09-09

最新评论