SpringBoot下Mybatis的缓存的实现步骤

SpringBoot下Mybatis的缓存实现步骤如下所述:

1. 配置缓存

在 Spring Boot 中,使用 Mybatis 需要先在 pom.xml 文件中引入相关的依赖和插件,然后在 application.yml 或 application.properties 文件中配置Mybatis即可。

在配置的时候,需要在 mybatis-config.xml 文件中进行相关的配置,启用二级缓存功能,具体的步骤如下:

  1. 在 mybatis-config.xml 配置文件中加入以下配置:
<settings>
    <setting name="cacheEnabled" value="true" />
    <setting name="localCacheScope" value="SESSION" />
    <setting name="lazyLoadingEnabled" value="true" />
    <setting name="aggressiveLazyLoading" value="false" />
    <setting name="defaultExecutorType" value="SIMPLE" />
    <setting name="defaultStatementTimeout" value="25000" />
    <setting name="mapUnderscoreToCamelCase" value="true" />
</settings>
  1. 在 Mapper.xml 文件中指定缓存策略:

  2. 标签中加入以下代码:

<mapper namespace="com.example.mapper.UserMapper">
    <cache type="org.mybatis.caches.ehcache.EhcacheCache"/>
    <!-- 或者:<cache type="org.mybatis.caches.memcached.MemcachedCache"/> -->
</mapper>

2. Mybatis 缓存实现

Mybatis 的缓存可以分为一级缓存和二级缓存。 二级缓存是进程级的缓存,是需要外部存储支持的;而一级缓存如下所述:

2.1 一级缓存

Mybatis 中默认开启了一级缓存,一级缓存是 session 级别的缓存,也就是说,如果执行多次相同的查询,只有第一次会连接数据库取出数据,后面的查询直接从缓存中拿数据。

为了验证一级缓存的有效性,可以根据以下的代码示例进行操作:

@Test
public void testLevelOneCache() throws Exception {
    SqlSession sqlSession = sqlSessionFactory.openSession();
    UserMapper mapper = sqlSession.getMapper(UserMapper.class);

    // 第一次查询 id 为 1 的用户
    User user1 = mapper.selectUserById(1L);
    System.out.println(user1);

    // 第二次查询 id 为 1 的用户
    User user2 = mapper.selectUserById(1L);
    System.out.println(user2);

    // 第三次查询 id 为 1 的用户,使用了一次 Mysql 命令行,触发了 cacheKey 参数变化
    User user3 = mapper.selectUserById(1L);
    System.out.println(user3);

    // 第四次查询 id 为 2 的用户
    User user4 = mapper.selectUserById(2L);
    System.out.println(user4);

    sqlSession.close();
}

输出如下:

DEBUG [main] - ooo Using Connection [HikariProxyConnection@595845868 wrapping com.mysql.cj.jdbc.ConnectionImpl@6c499008] 
DEBUG [main] - ==>  Preparing: select * from user where id=? 
DEBUG [main] - ==> Parameters: 1(Long) 
DEBUG [main] - ooo Using Connection [HikariProxyConnection@595845868 wrapping com.mysql.cj.jdbc.ConnectionImpl@6c499008] 
DEBUG [main] - ====>  Preparing: select * from user where id=? 
DEBUG [main] - ====> Parameters: 1(Long) 
DEBUG [main] - <====      Total: 1
User{id=1, name='Tom', age=20, address='Beijing'}
User{id=1, name='Tom', age=20, address='Beijing'}
DEBUG [main] - ooo Using Connection [HikariProxyConnection@595845868 wrapping com.mysql.cj.jdbc.ConnectionImpl@6c499008] 
DEBUG [main] - ==>  Preparing: select * from user where id=? 
DEBUG [main] - ==> Parameters: 1(Long) 
DEBUG [main] - ooo Using Connection [HikariProxyConnection@595845868 wrapping com.mysql.cj.jdbc.ConnectionImpl@6c499008] 
DEBUG [main] - ====>  Preparing: select * from user where id=? 
DEBUG [main] - ====> Parameters: 1(Long) 
DEBUG [main] - <====      Total: 1
User{id=1, name='Tom', age=20, address='Beijing'}
DEBUG [main] - ooo Using Connection [HikariProxyConnection@595845868 wrapping com.mysql.cj.jdbc.ConnectionImpl@6c499008] 
DEBUG [main] - ==>  Preparing: select * from user where id=? 
DEBUG [main] - ==> Parameters: 1(Long) 
DEBUG [main] - ooo Using Connection [HikariProxyConnection@595845868 wrapping com.mysql.cj.jdbc.ConnectionImpl@6c499008] 
DEBUG [main] - ====>  Preparing: select * from user where id=? 
DEBUG [main] - ====> Parameters: 1(Long) 
DEBUG [main] - <====      Total: 1
User{id=1, name='Tom', age=20, address='Beijing'}
DEBUG [main] - ooo Using Connection [HikariProxyConnection@595845868 wrapping com.mysql.cj.jdbc.ConnectionImpl@6c499008] 
DEBUG [main] - ==>  Preparing: select * from user where id=? 
DEBUG [main] - ==> Parameters: 2(Long) 
DEBUG [main] - ooo Using Connection [HikariProxyConnection@595845868 wrapping com.mysql.cj.jdbc.ConnectionImpl@6c499008] 
DEBUG [main] - ====>  Preparing: select * from user where id=? 
DEBUG [main] - ====> Parameters: 2(Long) 
DEBUG [main] - <====      Total: 1
User{id=2, name='Lisi', age=21, address='Shanghai'}

从输出可以看出,第一次查询 id 为 1 的用户时,会真正去获取数据;而第三次查询 id 为 1 的用户时,因为 cacheKey 参数并没有发生变化,所以使用了缓存中的缓存结果。

2.2 二级缓存

Mybatis 的二级缓存是基于 SqlSession 进行的缓存,是多个 SqlSession 共享的,也就是说,如果多个 SqlSession 对同一条 SQL 语句进行查询操作,可以共享二级缓存。

为了在 Mybatis 中开启二级缓存,需要在 Mybatis 全局配置文件中进行配置。

在 mybatis-config.xml 文件中加入以下配置:

<configuration>
    <settings>
        <setting name="cacheEnabled" value="true"/>
        <setting name="lazyLoadingEnabled" value="true"/>
        <setting name="aggressiveLazyLoading" value="false"/>
        <setting name="defaultExecutorType" value="SIMPLE"/>
    </settings>
    <typeAliases>
        <typeAlias type="com.example.entity.User" alias="User"/>
    </typeAliases>
    <!-- 配置二级缓存 -->
    <cache type="org.mybatis.caches.ehcache.EhcacheCache"/>
    <mappers>
        <mapper resource="mapper/UserMapper.xml"/>
    </mappers>
</configuration>

当然,如果你想要使用其他的二级缓存插件,只需要将 org.mybatis.caches.ehcache.EhcacheCache 替换为其他的缓存插件即可。

为了验证二级缓存的有效性,可以根据以下的示例进行操作:

/**
 * 测试二级缓存的有效性
 * 对于同一 SQL 语句,不同的 SqlSession 对象之间共享同一个二级缓存空间。
 * 在一个 SqlSession 中,二级缓存只缓存当前 Session 的数据,并且持续时间中数据会在更新的时候失效。
 * 在使用同一个 SqlSession 的情况下,不同的查询只会进入一次缓存,由于是一个 Session 所以查询的结果是相同的,如果进行 commit 操作,缓存将会失效。
 *
 * @throws Exception
 */
@Test
@Ignore("需要在缓存插件的 ehcache.xml 配置 LRU 策略,否则会出现缓存失效" )
public void testLevelTwoCache() throws Exception {
    SqlSession sqlSession1 = sqlSessionFactory.openSession();
    UserMapper mapper1 = sqlSession1.getMapper(UserMapper.class);

    // 第一次查询 id 为2的用户,会触发查询数据库,缓存命中为 false
    User user1 = mapper1.selectUserById(2L);
    System.out.println(user1 + ", cache hit=" + sqlSession1.getStatistics().isSecondLevelCacheEnabled());

    sqlSession1.close();

    // 开启第二个 SqlSession 对象
    SqlSession sqlSession2 = sqlSessionFactory.openSession();
    UserMapper mapper2 = sqlSession2.getMapper(UserMapper.class);

    // 第二次查询 id 为2的用户,会尝试从缓存中获取,缓存命中为 true
    User user2 = mapper2.selectUserById(2L);
    System.out.println(user2 + ", cache hit=" + sqlSession2.getStatistics().isSecondLevelCacheEnabled());

    // 第三次查询 id 为2的用户,会尝试从缓存中获取,缓存命中为 true
    User user3 = mapper2.selectUserById(2L);
    System.out.println(user3 + ", cache hit=" + sqlSession2.getStatistics().isSecondLevelCacheEnabled());

    // 提交事务,清空缓存
    sqlSession2.commit();

    // 第四次查询 id 为2的用户,因为缓存已经被清空,所以会重新查询数据库
    User user4 = mapper2.selectUserById(2L);
    System.out.println(user4 + ", cache hit=" + sqlSession2.getStatistics().isSecondLevelCacheEnabled());

    sqlSession2.close();
}

输出如下:

DEBUG [main] - ooo Using Connection [HikariProxyConnection@595845868 wrapping com.mysql.cj.jdbc.ConnectionImpl@6c499008] 
DEBUG [main] - ==>  Preparing: select * from user where id=? 
DEBUG [main] - ==> Parameters: 2(Long) 
DEBUG [main] - <==      Total: 1
User{id=2, name='Lisi', age=21, address='Shanghai'}, cache hit=false
User{id=2, name='Lisi', age=21, address='Shanghai'}, cache hit=true
User{id=2, name='Lisi', age=21, address='Shanghai'}, cache hit=true
DEBUG [main] - ooo Using Connection [HikariProxyConnection@19438362 wrapping com.mysql.cj.jdbc.ConnectionImpl@1939476295] 
DEBUG [main] - ==>  Preparing: select * from user where id=? 
DEBUG [main] - ==> Parameters: 2(Long) 
DEBUG [main] - <==      Total: 1
User{id=2, name='Lisi', age=22, address='Beijing'}, cache hit=false

从输出可以看出,同一个SQL只有一个查询会真正访问数据库,其他的查询都是从二级缓存中获取到的。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:SpringBoot下Mybatis的缓存的实现步骤 - Python技术站

(0)
上一篇 2023年5月20日
下一篇 2023年5月20日

相关文章

  • JAVA如何获取客户端IP地址和MAC地址

    获取客户端IP地址和MAC地址是Java开发中经常用到的技巧,下面将详细介绍如何实现。 获取客户端IP地址 在Java中获取客户端IP地址需要先获取请求头中的IP地址,然后通过这个IP地址去判断客户端具体的位置。以下是获取IP地址的代码: // 获取HttpServletRequest对象 HttpServletRequest request = (Http…

    Java 2023年5月26日
    00
  • 详解SpringBoot项目整合Vue做一个完整的用户注册功能

    我们来详细讲解一下“详解SpringBoot项目整合Vue做一个完整的用户注册功能”。这个攻略分两个部分:服务器端和客户端。我们分别来讲解。 服务器端 1. 创建SpringBoot项目 首先,我们需要在IDE中创建一个SpringBoot项目。可以使用Spring Initializr创建一个简单的Java Web项目,或者自己使用Maven创建。 2. …

    Java 2023年5月20日
    00
  • java jdbc连接和使用详细介绍

    Java JDBC连接和使用详细介绍 什么是JDBC? JDBC(Java Database Connectivity)是Java语言操作数据库的统一接口,它为访问不同的数据库提供了一个标准的类库。使用JDBC可以实现Java和数据库的交互操作。 JDBC步骤 使用JDBC进行数据库操作主要包括以下步骤: 加载JDBC驱动程序 建立数据库连接 创建Prepa…

    Java 2023年5月23日
    00
  • JAVA基于静态数组实现栈的基本原理与用法详解

    JAVA基于静态数组实现栈的基本原理与用法详解 1.概述 在计算机科学中,栈是一种常见的数据结构。栈数据结构可以看作是一个后进先出(LIFO)的数据容器。元素进入栈的顺序是后进先出,也就是说,最新的元素插入的位置在所有其他元素的顶部,而删除并返回的元素始终是当前元素中的“顶部”元素。本文主要介绍基于静态数组实现栈的基本原理与用法。 2.静态数组 静态数组就是…

    Java 2023年5月26日
    00
  • 使用java写的矩阵乘法实例(Strassen算法)

    使用Java编写矩阵乘法实例 算法介绍 Strassen算法是一种快速的矩阵乘法算法,该算法的时间复杂度为O(n^log7)。相比于传统的矩阵乘法算法,在矩阵规模非常大时,Strassen算法可以显著减少计算量,提高计算效率。因此,它经常被应用于科学计算、数据分析等领域。 Strassen算法核心思想 Strassen算法的核心思想是:将一个nn的矩阵A分解…

    Java 2023年5月19日
    00
  • Java工具类DateUtils实例详解

    Java工具类DateUtils实例详解 在Java开发中,经常会用到日期时间的操作。Java提供了丰富的日期时间类库,其中DateUtils工具类是常用的日期时间工具类之一。本文将详细介绍DateUtils的使用方法以及示例。 1. DateUtils类简介 DateUtils是Apache Commons Lang 3.0库中提供的日期时间工具类。它提供…

    Java 2023年6月1日
    00
  • SpringBoot 日志的配置及输出应用教程

    SpringBoot 日志的配置及输出应用教程 介绍 在开发过程中,日志是非常重要的。它可以帮助开发者了解应用程序中的每个步骤,并且帮助解决问题。Spring Boot 提供了多种日志框架,如 Logback、Log4j2、Java Util Logging 和 Commons Logging 等。这篇教程将详细介绍 SpringBoot 日志的配置及输出应…

    Java 2023年5月26日
    00
  • java计算两个日期中间的时间

    如果想要计算两个日期中间的时间,可以使用Java的Date和Calendar类来处理,具体步骤如下: 使用SimpleDateFormat类将输入的两个日期字符串转换为Date对象。 String startDate = "2021-01-01"; String endDate = "2021-06-30"; Simp…

    Java 2023年5月20日
    00
合作推广
合作推广
分享本页
返回顶部