【金九银十面试必问】Mybatis的一级缓存和二级缓存区别和联系以及如何配置

一、前言

MyBatis 是一种基于 Java 的持久层框架,它提供了一套方便的数据库访问方式,并且支持多种缓存机制来提高性能。在 MyBatis 中,有一级缓存和二级缓存两种缓存机制。

一级缓存特点:

一级缓存是 MyBatis 默认开启的缓存机制,它是基于 SqlSession 的缓存。当执行查询语句时,如果查询条件和 SQL 语句完全一致,MyBatis 会将查询结果缓存在 SqlSession 中。下次再执行相同的查询语句时,MyBatis 会先从缓存中查找,如果找到则直接返回缓存中的结果,避免了再次查询数据库的开销。

一级缓存的特点如下:

  1. 一级缓存的作用域是 SqlSession,同一个 SqlSession 内的多次查询可以共享同一个缓存。
  2. 一级缓存是默认开启的,可以在配置文件中通过 来关闭一级缓存。
  3. 一级缓存是自动刷新的,如果执行了增删改操作,会自动清空一级缓存。

二级缓存特点:

二级缓存是基于 Mapper 接口的缓存,它可以跨 SqlSession 共享缓存。当执行查询语句时,如果命中了二级缓存,MyBatis 会直接从缓存中返回结果,不再执行查询操作。

二级缓存的特点如下:

  1. 二级缓存的作用域是 Mapper 接口,多个 SqlSession 可以共享同一个 Mapper 接口的二级缓存。
  2. 二级缓存需要手动开启,可以在映射文件的 标签下添加 标签来配置缓存的属性。
  3. 二级缓存默认是开启的,但是每个 Mapper 接口的缓存是相互独立的,不同的 Mapper 接口可以有不同的缓存配置和缓存实例。
  4. 二级缓存可以使用各种缓存实现,默认使用的是 PerpetualCache,也可以使用其他的缓存实现,如 Ehcache、Redis 等。
  5. 二级缓存的刷新机制是基于更新操作的,当执行了增删改操作,会清空对应的 Mapper 接口的缓存。

需要注意的是,一级缓存和二级缓存是独立的,它们并不是同一个缓存实例。一级缓存是针对单个 SqlSession 的,而二级缓存是针对 Mapper 接口的。所以,如果使用了二级缓存,在同一个 SqlSession 中执行增删改操作不会影响二级缓存,但会自动刷新一级缓存。而如果是在不同的 SqlSession 中执行增删改操作,则会影响二级缓存。

二、代码说明

一级缓存说明:

当使用一级缓存时,假设有以下的代码片段:

SqlSession sqlSession = sessionFactory.openSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);

// 第一次查询,会从数据库中获取数据,并将结果缓存到一级缓存中
User user1 = userMapper.getUserById(1);
System.out.println(user1);

// 第二次查询,由于查询条件和 SQL 语句完全一致,直接从一级缓存中获取结果
User user2 = userMapper.getUserById(1);
System.out.println(user2);

sqlSession.close();

在上述代码中,第一次查询会从数据库中获取数据,并将结果缓存到一级缓存中。第二次查询时,由于查询条件和 SQL 语句完全一致,所以直接从一级缓存中获取到了结果。这样就避免了第二次去数据库查询的开销。

二级缓存说明:

当使用二级缓存时,假设有以下的代码片段:

SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession sqlSession1 = sessionFactory.openSession();
SqlSession sqlSession2 = sessionFactory.openSession();

UserMapper userMapper1 = sqlSession1.getMapper(UserMapper.class);
UserMapper userMapper2 = sqlSession2.getMapper(UserMapper.class);

// 第一次查询,会从数据库中获取数据,并将结果缓存到二级缓存中
User user1 = userMapper1.getUserById(1);
System.out.println(user1);

// 关闭 sqlSession1,将二级缓存中的数据写入到磁盘中
sqlSession1.close();

// 第二次查询,命中了二级缓存,直接从缓存中获取结果
User user2 = userMapper2.getUserById(1);
System.out.println(user2);

sqlSession2.close();

在上述代码中,第一次查询会从数据库中获取数据,并将结果缓存到二级缓存中。然后关闭 sqlSession1,将二级缓存中的数据写入到磁盘中。第二次查询时,由于命中了二级缓存,所以直接从缓存中获取到了结果,无需再次查询数据库。

需要注意的是,二级缓存是跨 SqlSession 的,所以可以在不同的 SqlSession 中共享缓存。但是当执行增删改操作时,会清空对应的 Mapper 接口的二级缓存,以保证缓存的一致性。

三、如何配置

spring、springMVC配置

或者是mybatis.xml文件配置
或者是单个mapper配置

一级缓存和二级缓存的配置都是通过 MyBatis 的配置文件进行配置。

配置一级缓存:

在 MyBatis 的配置文件(通常是 mybatis-config.xml)中,可以通过 标签来配置一级缓存的相关属性。常用的一级缓存配置选项包括:

  • localCacheScope:指定一级缓存的作用域,默认为 SESSION,表示在一个会话范围内有效。可以设置为 STATEMENT,表示在一个语句范围内有效。
  • cacheEnabled:指定是否开启一级缓存,默认为 true 开启。

示例配置一级缓存的配置项:

<configuration>
  <settings>
    <setting name="localCacheScope" value="SESSION"/>
    <setting name="cacheEnabled" value="true"/>
  settings>
  ...
configuration>

配置二级缓存:

在 MyBatis 的配置文件中,可以通过 标签来配置二级缓存的相关属性。常用的二级缓存配置选项包括:

  • type:指定二级缓存的具体实现类。可以使用 MyBatis 内置的实现类,如 org.apache.ibatis.cache.impl.PerpetualCache,也可以自定义实现类。
  • eviction:指定缓存的清除策略,默认为 LRU(最近最少使用),还可以配置为 FIFO(先进先出)或 SOFT(软引用)等。
  • flushInterval:指定缓存的刷新间隔,单位为毫秒。
  • readOnly:指定缓存是否只读,默认为 false。

示例配置二级缓存的配置项:

<configuration>
  <settings>
    ...
  settings>

  <typeAliases>
    ...
  typeAliases>

  <mappers>
    ...
  mappers>

  <cache type="org.apache.ibatis.cache.impl.PerpetualCache"
         eviction="LRU"
         flushInterval="60000"
         readOnly="false"/>
configuration>

需要注意的是,配置二级缓存还需要在具体的 Mapper 接口中开启二级缓存的使用,可以通过在 Mapper 接口的 标签中添加 cache 属性来开启二级缓存的使用。

<mapper namespace="com.example.mapper.UserMapper" cache-ref="myCache"/>

在上述示例中,cache-ref 属性指向了 标签的 id,表示使用指定的二级缓存。

springBoot配置

在 Spring Boot 项目中,配置一级缓存和二级缓存的方式略有不同。下面分别介绍在 Spring Boot 项目中如何配置一级缓存和二级缓存。

配置一级缓存:

在 Spring Boot 项目中,可以通过在 application.propertiesapplication.yml 文件中配置相关属性来配置一级缓存。常用的一级缓存配置属性包括:

  • mybatis.configuration.local-cache-scope:指定一级缓存的作用域,默认为 SESSION,表示在一个会话范围内有效。可以设置为 STATEMENT,表示在一个语句范围内有效。
  • mybatis.configuration.cache-enabled:指定是否开启一级缓存,默认为 true 开启。

示例配置一级缓存的属性:

application.properties 文件中:

mybatis.configuration.local-cache-scope=SESSION
mybatis.configuration.cache-enabled=true

application.yml 文件中:

mybatis:
  configuration:
    local-cache-scope: SESSION
    cache-enabled: true

配置二级缓存:

在 Spring Boot 项目中,可以通过在 application.propertiesapplication.yml 文件中配置相关属性来配置二级缓存。常用的二级缓存配置属性包括:

  • mybatis.configuration.cache-enabled:指定是否开启二级缓存,默认为 true 开启。
  • mybatis.configuration.eviiction:指定缓存的清除策略,默认为 LRU(最近最少使用),还可以配置为 FIFO(先进先出)或 SOFT(软引用)等。
  • mybatis.configuration.flush-interval:指定缓存的刷新间隔,单位为毫秒。
  • mybatis.configuration.read-only:指定缓存是否只读,默认为 false。

示例配置二级缓存的属性:

application.properties 文件中:

mybatis.configuration.cache-enabled=true
mybatis.configuration.eviction=LRU
mybatis.configuration.flush-interval=60000
mybatis.configuration.read-only=false

application.yml 文件中:

mybatis:
  configuration:
    cache-enabled: true
    eviction: LRU
    flush-interval: 60000
    read-only: false

需要注意的是,配置二级缓存还需要在具体的 Mapper 接口上添加 @Mapper 注解并开启二级缓存的使用。

@Mapper
public interface UserMapper {
    ...
}

在上述示例中,@Mapper 注解表示将该接口注册为 MyBatis 的 Mapper 接口,使其能够被 MyBatis 扫描并生成对应的实现类。开启二级缓存的使用则需要在 application.propertiesapplication.yml 文件中添加以下配置:

mybatis.configuration.cache-enabled=true

mybatis:
  configuration:
    cache-enabled: true

以上就是大概mybatis的基础使用知识,如果有不懂的,欢迎留言

你可能感兴趣的:(MyBatis知识技巧,数据库知识,面试这么回答,mybatis,面试,缓存)