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日

相关文章

  • Tomcat中的catalina.bat原理详细解析

    Tomcat中的catalina.bat原理详细解析 什么是catalina.bat? catalina.bat是Tomcat的启动脚本之一。在Windows下,Tomcat是通过执行catalina.bat实现启动和关闭的。该脚本文件位于Tomcat的bin目录下。 catalina.bat的作用 catalina.bat实现了Tomcat的启动、关闭、重…

    Java 2023年5月20日
    00
  • Java实现十秒向MySQL插入百万条数据

    Java实现十秒向MySQL插入百万条数据,需要注意以下几个方面: 使用JDBC方式连接MySQL数据库 Java对于MySQL数据库的连接,可以使用JDBC方式,Java提供了java.sql包,其中包含了用于连接数据库和执行SQL语句的类和接口。我们需要将mysql-connector-java.jar添加到我们的项目中,以便能够使用JDBC连接MySQ…

    Java 2023年5月20日
    00
  • java多媒体文件编码 处理工具类代码实例

    Java多媒体文件编码处理工具类 本文将详细讲解如何使用Java多媒体文件编码处理工具类来编码、解码、转换和编辑多媒体文件。 什么是Java多媒体文件编码处理工具类? Java多媒体文件编码处理工具类是一个Java库,提供了编码、解码、转换和编辑多媒体文件的功能。它支持音频和视频文件的处理,其中包括: 音频格式:MP3、WAV、AIFF、AU、FLAC、OG…

    Java 2023年5月19日
    00
  • 品味布隆过滤器的设计之美

    布隆过滤器是一个精巧而且经典的数据结构。 你可能没想到: RocketMQ、 Hbase 、Cassandra 、LevelDB 、RocksDB 这些知名项目中都有布隆过滤器的身影。 对于后端程序员来讲,学习和理解布隆过滤器有很大的必要性。来吧,我们一起品味布隆过滤器的设计之美。 1 缓存穿透 我们先来看一个商品服务查询详情的接口: public Prod…

    Java 2023年4月17日
    00
  • 详解Java中自定义注解的使用

    下面是详解Java中自定义注解的使用的完整攻略。 什么是注解 注解是Java语言中的元数据,是JDK5.0版本以后新增的特性。它可以为Java代码提供额外的信息,被用于代码的分析、编译和运行时的处理等操作。注解本身不会对代码的逻辑产生影响,它只是提供了额外的元数据信息,使得程序员可以在代码上进行更精细的控制。 自定义注解的基本结构 自定义注解定义格式位于Ja…

    Java 2023年5月26日
    00
  • Spring入门实战之Profile详解

    以下是 “Spring入门实战之Profile详解”的完整攻略: 什么是 Spring Profile Spring是一个非常流行的 JavaEE 框架,它提供了许多元数据、配置和依赖注入等功能,便于我们快速构建应用程序。Spring Profile 是 Spring 框架中一项非常有用的功能。它可以用于定义可重用的配置、属性文件、JavaBean、组件等,…

    Java 2023年5月19日
    00
  • Java代码中如何设置输出字符集为UTF-8

    在Java代码中,我们可以通过设置输出流的字符集来确保我们的输出内容符合我们在程序中预期的编码方式。下面是关于如何设置Java代码输出字符集为UTF-8的完整攻略: 1. 设置System.out的字符集为UTF-8 设置System.out的字符集为UTF-8的方法是通过调用System.setOut()方法,并将PrintWriter的实例传递给该方法。…

    Java 2023年6月1日
    00
  • 老生常谈Java字符串进阶(必看篇)

    老生常谈Java字符串进阶(必看篇) 一、字符串不可变性 1.1 什么是字符串不可变性? Java中的字符串是immutable(不可变)的,即一旦字符串被创建,就不能够被修改。这意味着,每次对字符串进行修改操作时,都会创建一个新的字符串。例如: String str = "hello"; str = str + " world…

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