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)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • mysql数据库报错1146_关于MySQL报错:[ERR] 1146

    mysql数据库报错1146_关于MySQL报错:[ERR] 1146最近因为电脑重装了系统,导致自己原本的数据库呗覆盖,需要重新重新安装数据库,但是由于我之前数据库版本是mysql5.0.22,版本太低,所以小编决定安装mysql5.7.23版本的,一开始没什么问题,根据之前的安装路径安装成功后,接着配置了mysql的环境变量mysql_path,,然后在数据库编辑工具NavicatforMySQL打开后,进行了一个小小的数据库查询:select*fr…

    2022年5月24日
    193
  • 基于Java swing+mysql+eclipse的【图书管理系统】

    基于Java swing+mysql+eclipse的【图书管理系统】一、效果演示:主要功能:①基本数据维护:图书类别管理>>图书类别添加、图书类别维护图书管理>>图书添加、图书维护②关于我们1、登录界面2、主界面:3、图书类别维护4、图书类别添加5、图书维护6、图书添加7、关于我们可全部缩小到左下角二、核心代码:1、Util包【存放数据库连接工具】①DBTool(数据库连接工具类)packagecn.ac.azure.util;importjava.io.IOException

    2022年6月9日
    31
  • JavaScript实现 满天星 导航栏

    说明分享一个满天星导航栏的效果,代码不多,但效果挺好看,先看看效果图吧。解释实现这个效果,需要掌握的知识不用很多,知道简单的CSS,会用JS获取元素,能绑定事件基本就足够了。好的,我们直接来看代码,注释已经写的很详细了,不想看有注释的,点这里。

    2022年4月8日
    51
  • vue 页面关闭_vue怎么关闭滴一声

    vue 页面关闭_vue怎么关闭滴一声关闭vue中的ESLint

    2022年10月8日
    2
  • 富文本框_html表单输入框对齐

    富文本框_html表单输入框对齐1.HTML代码:<trid="illegal"><th></th><tdcolspan="3"style

    2022年8月2日
    10
  • log4j2的使用_logback log4j

    log4j2的使用_logback log4j一、目录简介基础部分日志框架简单比较(slf4j、log4j、logback、log4j2)log4j2基础知识log4j2实用配置实战部分slf4j+log4j2实际使用二、日志框架比较(slf4j、log4j、logback、log4j2)日志接口(slf4j)slf4j是对所有日志框架制定的一种规范、标准、接口,并不是一个框架的具体的实现,因为接口并不能独立使

    2025年9月15日
    7

发表回复

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

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