Mybatis一级缓存和二级缓存

在 MyBatis 中,一级缓存二级缓存 是两种用于提高查询性能的缓存机制。它们通过缓存数据库查询结果,避免每次都从数据库读取数据,从而减少数据库的负载并提高应用性能。

1. 一级缓存(一级缓存)

一级缓存是 MyBatis 的 本地缓存,作用范围限于 SqlSession。每次通过同一个 SqlSession 执行查询时,查询结果会被缓存下来。如果在同一个 SqlSession 中执行相同的查询,MyBatis 会直接从缓存中返回结果,而不是重新发送 SQL 请求到数据库。

特点:
  • 作用范围:限于当前 SqlSession
  • 生命周期SqlSession 的生命周期内,一级缓存有效。如果 SqlSession 被关闭,则缓存会被清除。
  • 默认启用:一级缓存是 MyBatis 的默认行为,不需要额外配置。
  • 存储:缓存存储在 SqlSession 内存中,基于 HashMap 进行存储,查询条件作为键,查询结果作为值。
工作原理:
  1. 第一次执行查询时,MyBatis 会向数据库发送 SQL 查询,并将查询结果存储在一级缓存中。
  2. 如果在同一个 SqlSession 中再次执行相同的查询,MyBatis 会首先检查一级缓存中是否已经有结果。如果有,直接从缓存中返回结果,不再查询数据库。

 示例:一级缓存的工作原理

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

// 第一次查询,执行数据库操作
User user1 = userMapper.selectUserById(1);

// 第二次查询,结果将从一级缓存中获取,而不执行数据库操作
User user2 = userMapper.selectUserById(1);

sqlSession.close();

在上述代码中,第一次执行查询时,查询结果会被存储在一级缓存中。当第二次执行相同查询时,结果会直接从缓存中返回,避免了再次查询数据库。

清空一级缓存
  • 当调用 sqlSession.clearCache() 时,会清空一级缓存。
  • SqlSession 被关闭时,一级缓存也会被清空。

 

2. 二级缓存(二级缓存)

二级缓存是 MyBatis 提供的 SqlSession 的缓存机制,它的作用范围是 整个 Mapper整个 SqlSessionFactory。不同的 SqlSession 可以共享二级缓存,从而有效地减少数据库的查询次数。

特点:
  • 作用范围:跨 SqlSession
  • 生命周期:当 SqlSessionFactory 被销毁时,二级缓存才会失效。它的生命周期比一级缓存长。
  • 默认禁用:二级缓存默认是关闭的,需要在配置文件中显式启用。
  • 存储:二级缓存可以配置使用不同的缓存存储机制(如内存缓存、外部缓存系统等),并且通常使用缓存框架(如 EHCache、Redis 等)来实现。
启用二级缓存

要启用二级缓存,首先需要在 MyBatis 的配置文件 mybatis-config.xml 中启用二级缓存,并在对应的 Mapper 文件中配置缓存。

配置 mybatis-config.xml 启用二级缓存
<configuration>
    <settings>
        <setting name="cacheEnabled" value="true"/>
    </settings>
</configuration>

 cacheEnabled 设置为 true 以启用二级缓存。

 

配置 Mapper 文件启用缓存

在每个需要使用二级缓存的 Mapper 文件中,使用 <cache> 标签来启用缓存。

<mapper namespace="com.example.mapper.UserMapper">
    <cache eviction="LRU" flushInterval="60000" size="512" readOnly="false" />
    
    <select id="selectUserById" resultType="com.example.model.User">
        SELECT * FROM users WHERE id = #{id}
    </select>
</mapper>

在上面的 Mapper 配置中:

  • <cache> 标签启用了二级缓存,并配置了缓存的一些属性,如:
    • eviction:指定缓存的淘汰策略,如 LRU(Least Recently Used)策略。
    • flushInterval:指定刷新缓存的时间间隔(以毫秒为单位)。
    • size:指定缓存的最大容量。
    • readOnly:是否设置为只读缓存,如果为 true,表示缓存中的数据不可修改。
工作原理:
  1. 当执行查询时,MyBatis 会首先检查二级缓存中是否有该查询的结果。如果存在,直接从缓存中读取结果。
  2. 如果二级缓存中没有结果,MyBatis 会执行数据库查询,将查询结果存储到二级缓存中,并返回给客户端。
  3. 在后续的 SqlSession 中,若再次执行相同的查询,将从二级缓存中获取结果,而不再查询数据库。

示例:二级缓存的工作原理

SqlSession sqlSession1 = sqlSessionFactory.openSession();
UserMapper userMapper1 = sqlSession1.getMapper(UserMapper.class);

// 第一次查询,查询结果存储到二级缓存
User user1 = userMapper1.selectUserById(1);

sqlSession1.close(); // 关闭 sqlSession1

SqlSession sqlSession2 = sqlSessionFactory.openSession();
UserMapper userMapper2 = sqlSession2.getMapper(UserMapper.class);

// 第二次查询,结果会从二级缓存中获取
User user2 = userMapper2.selectUserById(1);

sqlSession2.close(); // 关闭 sqlSession2

 

在这个例子中:

  1. 第一次查询时,结果会存储在二级缓存中。
  2. 即使使用不同的 SqlSessionsqlSession1sqlSession2),如果执行相同的查询,MyBatis 会从二级缓存中返回结果,而不再查询数据库。

3. 二级缓存的失效条件

二级缓存会在以下情况下失效:

  • 数据库中相关数据发生变化(如更新、删除、插入等操作)。
  • 调用 clearCache() 方法或 commit()rollback() 时,会清空二级缓存。
  • 二级缓存配置了超时时间,当缓存数据过期时,缓存会被清空。

4. 一级缓存与二级缓存的区别总结

特性一级缓存(一级缓存)二级缓存(二级缓存)
作用范围当前 SqlSession 内部SqlSession,通常在 SqlSessionFactory 范围内
生命周期SqlSession 生命周期内有效,关闭时清空只要 SqlSessionFactory 存在,就有效
默认开启默认启用默认关闭,需显式配置启用
存储方式存储在 SqlSession 内存中可以使用内存或外部缓存存储(如 Redis、EHCache 等)
清除缓存SqlSession.close() 会清除一级缓存需要清除特定的二级缓存或进行 flush 操作
性能更快,通常用于在单一会话中重用数据适用于跨会话的缓存,减少数据库查询次数

5. 总结

  • 一级缓存:默认启用,作用范围限于当前 SqlSession,缓存的内容只会在同一个 SqlSession 内部重用。适用于局部的缓存需求,生命周期较短。
  • 二级缓存:需要显式配置,作用范围是整个 SqlSessionFactory,可以跨多个 SqlSession 重用缓存数据,适用于跨会话的缓存场景,能够有效提高性能,尤其是在读取量较大的应用中。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值