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 GUI图形界面开发实现小型计算器流程详解

    Java GUI图形界面开发实现小型计算器流程详解

    本文章向大家介绍Java GUI图形界面开发实现小型计算器,主要包括布局管理器使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下
    2022-08-08
  • Spring Profile与PropertyPlaceholderConfigurer项目多环境配置切换

    Spring Profile与PropertyPlaceholderConfigurer项目多环境配置切换

    这篇文章主要介绍了Spring Profile与PropertyPlaceholderConfigurer项目多环境配置切换方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-09-09
  • Java初学者常问的问题(推荐)

    Java初学者常问的问题(推荐)

    本文介绍一些Java初学者常问的问题,很多朋友对可以用%除以一个小数吗? a += b 和 a = a + b 的效果有区别吗? 声明一个数组为什么需要花费大量时间? 为什么Java库不用随机pivot方式的快速排序?等等一系列问题有疑惑,下面就通过本文给大家详细介绍下
    2017-03-03
  • Mybatis-Plus Wrapper条件构造器超详细使用教程

    Mybatis-Plus Wrapper条件构造器超详细使用教程

    接口方法的参数中,会出现各种 Wrapper,比如 queryWrapper、updateWrapper 等。Wrapper 的作用就是用于定义各种各样的条件(where)。所以不管是查询、更新、删除都会用到Wrapper
    2022-03-03
  • Idea中mapper注入报错问题及解决

    Idea中mapper注入报错问题及解决

    这篇文章主要介绍了Idea中mapper注入报错问题及解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-03-03
  • 百度Java面试题 前200页精选(中)

    百度Java面试题 前200页精选(中)

    这篇文章主要为大家分享了Java面试资源中篇,百度“Java面试题”前200页都在这里了,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-12-12
  • 解决springboot 实体类String转Date类型的坑

    解决springboot 实体类String转Date类型的坑

    这篇文章主要介绍了解决springboot 实体类String转Date类型的坑,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-10-10
  • 浅谈String、StringBuffer和StringBuilder之间的区别

    浅谈String、StringBuffer和StringBuilder之间的区别

    这篇文章主要介绍了浅谈String、StringBuffer和StringBuilder之间的区别,通过字面量方式为字符串赋值时,此时的字符串存储在方法区的字符串常量池中,需要的朋友可以参考下
    2023-10-10
  • Springboot整合Dubbo教程之项目创建和环境搭建

    Springboot整合Dubbo教程之项目创建和环境搭建

    本篇文章主要介绍了Springboot整合Dubbo教程之项目创建和环境搭建,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-12-12
  • kotlin java 混合代码 maven 打包实现

    kotlin java 混合代码 maven 打包实现

    这篇文章主要介绍了kotlin java 混合代码 maven 打包实现,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-03-03

最新评论