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)
上一篇 2022年5月21日 下午7:00
下一篇 2022年5月21日 下午7:00


相关推荐

  • JAVA 原子性和波动性总结 Atomicity and Volality

    JAVA 原子性和波动性总结 Atomicity and Volality原子性 Atomicity nbsp 简单来说就是指不能被中断的一次性操作 在 JAVA 中 除了 long 和 double 的基本类型的读和写都是原子操作 这里要注意 long 和 double 是 64 位的 他们的操作被分割为两个 32 位操作 因此对 long 和 double 的读和写不是原子操作 非原子操作在多线程环境中是会出问题的 不能达到预期 例如写一个函数 每次都返回某个变量 1 想要实现不同的线程

    2026年3月16日
    3
  • linux 命令行 查找文件_shell查找文件中指定的字符串

    linux 命令行 查找文件_shell查找文件中指定的字符串一grep:查看文件内容,在文件中查询一个关键字,即搜索字符串的命令(在指定的文件中搜索符合条件的字符串)grep是包含匹配,不是完全的精确匹配,特别适合查找内容语法:grep[-option]需要搜索的关键字文件名参数:-n—-连行号一起显示-c—-统计有几行-i—-忽略大小写(一般用的少)-v—-排除指定的字符串(了解),取反,查找出来的内容是搜索条件以外的所有的内容例如:[root@localhostTEST~]#grep-n

    2025年8月25日
    5
  • 蓝桥杯单片机DS18B02温度测量(小数点显示)

    蓝桥杯单片机DS18B02温度测量(小数点显示)

    2021年11月12日
    43
  • C语言中scanf函数详解「建议收藏」

    C语言中scanf函数详解「建议收藏」scanf函数  上一节中我们讨论了,如何将整数,浮点数,字符串打印到屏幕上去。既然有输出,怎么能没有输入呢?这一节中,我们来介绍与printf相反的scanf函数。  scanf的功能是将键盘输入的字符串转换成整数、浮点数、字符或字符串。1.scanf函数的使用公式scanf是一个变参函数。(参数的数量和类型不确定)scanf的第一个参数是字符串。scanf的第一个参数是需要输入的字符串以及需要被读取的占位符。scanf的后续参数,是依次被读取并赋值的变量地址。占位符的类型和数量需要与

    2025年6月30日
    4
  • opencv中resize函数怎么用(图像resize)

    opencv中的resize函数有多种用法:1,图像缩放opencv帮助文档中对resize函数的介绍:src输入图dst输出图,形态和输入图相同,当dsize不等于0,输出图尺寸会和dsize相同,当dsize等于0,输出图尺寸会由输入图尺寸、fx、fy计算而得dsize输出尺寸,当输入为0时,fx、fy皆不可为0,dsize=Size(round(fxsrc.cols),round(fysrc.rows))fx水平缩放比例,当输入为0时,fx=(do

    2022年4月17日
    309
  • CSS3:backgroud-size和background-origin的使用方法

    CSS3:backgroud-size和background-origin的使用方法

    2021年7月9日
    94

发表回复

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

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