Spring Boot – Mybatis 缓存

Spring Boot – Mybatis 缓存mybatis提供查询缓存,用于减轻数据压力,提高数据库性能。mybaits提供一级缓存和二级缓存。一级缓存一级缓存是sqlSession级别的缓存。在操作数据库时需要构造sqlSession对象,在对象中有一个(内存区域)数据结构(HashMap)用于存储缓存数据。不同的sqlSession之间的缓存数据区域(HashMap)是互相不影响的。一级缓存的作用域是同一个SqlSession,在同一个sqlSession中两次执行相同的sql语句,第一次执行完毕会将数据库中查询的数据写到缓存(内存

大家好,又见面了,我是你们的朋友全栈君。

mybatis提供查询缓存,用于减轻数据压力,提高数据库性能。mybaits提供一级缓存和二级缓存。

一级缓存

一级缓存是sqlSession级别的缓存。在操作数据库时需要构造 sqlSession对象,在对象中有一个(内存区域)数据结构(HashMap)用于存储缓存数据。不同的sqlSession之间的缓存数据区域(HashMap)是互相不影响的。

一级缓存的作用域是同一个SqlSession,在同一个sqlSession中两次执行相同的sql语句,第一次执行完毕会将数据库中查询的数据写到缓存(内存),第二次会从缓存中获取数据将不再从数据库查询,从而提高查询效率。当一个sqlSession结束后该sqlSession中的一级缓存也就不存在了。Mybatis默认开启一级缓存。

二级缓存

二级缓存是mapper级别的缓存,多个sqlSession去操作同一个Mapper的sql语句,操作数据库得到数据会存在二级缓存区域。多个sqlSession可以共用二级缓存,二级缓存是跨sqlSession的。

二级缓存是多个sqlSession共享的,其作用域是mapper的同一个namespace,不同的sqlSession两次执行相同namespace下的sql语句且向sql中传递参数也相同即最终执行相同的sql语句,第一次执行完毕会将数据库中查询的数据写到缓存(内存),第二次会从缓存中获取数据将不再从数据库查询,从而提高查询效率。Mybatis默认没有开启二级缓存,需要在setting全局参数中配置开启二级缓存。

Spring 中的缓存

Spring与MyBatis整合时,MyBatis的一级缓存在没有事务存在的时候失效。

在未开启事务的情况之下,每次查询,spring都会关闭旧的sqlSession而创建新的sqlSession,因此此时的一级缓存是没有启作用的。

在开启事务的情况之下,spring使用threadLocal获取当前资源绑定同一个sqlSession,因此此时一级缓存是有效的。

SpringBoot中默认帮我们全局开启了二级缓存,如果想要使用二级缓存还需要在mapper上注明。

注解版使用@CacheNamespace注解(为给定的命名空间(比如类)配置缓存,对应xml<cache>)在该mapper上使用二级缓存。

@CacheNamespace

@CacheNamespace注解主要用于mybatis二级缓存,等同于<cache>属性。默认情况下,MyBatis 3 没有开启二级缓存,要开启二级缓存,需要在SQL 映射文件(mapper.xml)中添加一行:

<mapper namespace="cn.mybatis.mydemo.mapper.StudentMapper">
   <cache eviction="FIFO" flushInterval="60000" readOnly="false" size="1024"></cache>
</mapper>

当然,前提还需要在全局配置文件中开启缓存:

<setting name="cacheEnabled" value="true"/>

CacheNamespace是注解,其源码如下所示:

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface CacheNamespace {
  Class<? extends org.apache.ibatis.cache.Cache> implementation() default PerpetualCache.class;

  Class<? extends org.apache.ibatis.cache.Cache> eviction() default LruCache.class;

  long flushInterval() default 0;

  int size() default 1024;

  boolean readWrite() default true;
  
  boolean blocking() default false;

  Property[] properties() default {};

}

配置文件和接口注释配合使用时,需要在xml配置文件中配置<cache>属性, 同时在接口中修改注释为@CacheNamespaceRef。

@CacheNamespaceRef

Java里面没有指针,但是Java里面有引用,CacheNamespaceRef就是一个引用。它是谁的引用呢?请看源码注释:

A namespace type to reference a cache (the namespace name become a FQCN of specified type)

FQCN = Full Qualified Class Name

上面的意思就是想说明:CacheNamespaceRef当做CacheNamespace的短链接、快捷键,它是CacheNamespace的引用。

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface CacheNamespaceRef {
  /**
   * A namespace type to reference a cache (the namespace name become a FQCN of specified type)
   */
  Class<?> value() default void.class;
  /**
   * A namespace name to reference a cache
   * @since 3.4.2
   */
  String name() default "";
}

查看注解源码,value就是当前类,name是使用的Mapper接口的全限定名,以下三种写法都可以:

Spring Boot - Mybatis 缓存

CacheNamespaceRef的作用:

我们知道,MyBatis分为一级缓存和二级缓存。一级缓存是会话(session)级别的,二级缓存是应用(application)级别的。但是,MyBatis并不是简单地对整个Application就只有一个Cache缓存对象,它将缓存划分的更细,即是Mapper级别的,即每一个Mapper都可以拥有一个Cache对象,具体如下:
(1)为每一个Mapper分配一个Cache缓存对象(使用<cache>节点配置或者 @CacheNamespace注解 );
(2)多个Mapper共用一个Cache缓存对象(使用<cache-ref>节点配置或者本文所提到的@CacheNamespaceRef注解);

Mybatis 二级缓存示意图:

Spring Boot - Mybatis 缓存

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/143416.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • jQuery简洁大方的登录页面模板

    jQuery+CSS网站登录模板本模板带验证码在线体验:http://hovertree.com/texiao/jquery/13.htmDemo2:http://hovertree.com/hvt

    2021年12月21日
    54
  • simHash 简介以及 java 实现[通俗易懂]

    simHash 简介以及 java 实现[通俗易懂]simHash简介以及java实现

    2022年9月27日
    2
  • 炒黄金入门必备基础知识学习「建议收藏」

    炒黄金入门必备基础知识学习「建议收藏」黄金投资在西方发达国家已经有百年历史了,其运作流程、交易体系都越来越完善,而且投资市场也越来越成熟。黄金市场是国际金融投资的热点。伦敦的现货黄金市场、美国的黄金期货市场、香港金银业贸易场等地的黄金市场组成了全球24小时不间断的黄金投资市场。一、交易介绍国际现货黄金以保证金的方式进行的一种现货交易业务,买卖双方以一定比例的保证金确立买卖合约,该合约可以不必实物交收,买卖双方可以根据市场的变化情…

    2022年5月8日
    36
  • Intellij IDEA 2017 debug断点调试技巧与总结详解篇[通俗易懂]

    Intellij IDEA 2017 debug断点调试技巧与总结详解篇[通俗易懂]IntelliJIDEA使用教程(总目录篇)在调试代码的时候,你的项目得debug模式启动,也就是点那个绿色的甲虫启动服务器,然后,就可以在代码里面断点调试啦。下面不要在意,这个快捷键具体是啥,因为,这个keymap是可以自己配置的,有的人keymap是mac版的,有的是Windows版的。我的就是Windows,而且修改keymap为eclipse的keymap,因为我算是eclips…

    2022年5月11日
    52
  • mysql批量写入_mysql insert多条数据

    mysql批量写入_mysql insert多条数据最近新的项目写了不少各种insertBatch的代码,一直有人说,批量插入比循环插入效率高很多,那本文就来实验一下,到底是不是真的?测试环境:SpringBoot2.5 Mysql8 JDK8 Docker首先,多条数据的插入,可选的方案:foreach循环插入 拼接sql,一次执行 使用批处理功能插入搭建测试环境`sql文件:dropdatabaseIFEXISTStest;CREATEDATABASEtest;usetest;DROPT

    2022年10月6日
    2
  • 微服务中的日志管理 — ELK

    微服务中的日志管理 — ELK通过使用微服务,我们能够解决许多在单体应用中暴露的问题,并且它允许我们创建稳定的分布式应用程序,并对代码,团队规模,维护,发布周期,云计算等进行所需要的控制。但同时微服务也引入了一些挑战,例如分布式日志管理和查看。需要提供在众多服务中查看分布的完整事务日志和分布式调试的能力。实际上,挑战在于微服务是相互隔离的,它们不共享公共数据库和日志文件。随着微服务数量的增加以及我们使用自动化持续集成工具实现…

    2022年6月6日
    31

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号