mabatis缓存机制

本文详细介绍了MyBatis框架的一级和二级缓存机制,包括它们的工作原理、开启方式以及缓存失效的两种情况:更新操作和手动清除缓存。
摘要由CSDN通过智能技术生成

目录

简介

    一级缓存(本地缓存):

    二级缓存(全局缓存):

两个缓存失效的场景


简介

MyBatis是一个支持半自动化的持久层框架,它提供了缓存机制来优化数据库访问性能。MyBatis的缓存机制可以分为一级缓存和二级缓存两个层次。

    一级缓存(本地缓存):

        一级缓存是默认开启的,它是在SqlSession级别的缓存,即同一个SqlSession对象中,对于相同的查询语句,首次查询会将查询结果缓存起来,后续再次执行相同的查询语句时,会直接从缓存中获取结果,而不再发送SQL到数据库。

        一级缓存是基于对象引用的缓存,因此当SqlSession进行增删改操作时,会清空该SqlSession的一级缓存,保证缓存数据与数据库的一致性。

        一级缓存的生命周期与SqlSession的生命周期一致,即当SqlSession关闭后,一级缓存也会被清空。

    二级缓存(全局缓存):

        二级缓存是跨SqlSession的缓存,可以被多个SqlSession共享。

        二级缓存需要手动配置开启,在映射文件中的<cache>元素进行配置。

        当查询语句命中二级缓存时,会直接从缓存中获取结果,而不会再次发送SQL到数据库。

        二级缓存是基于序列化的方式实现的,因此缓存的对象需要实现Serializable接口。

        二级缓存的生命周期与整个应用的生命周期一致,在应用关闭前,缓存中的数据会一直存在。

两个缓存失效的场景

下面我们通过代码来详细讲解 MyBatis 的缓存机制,并举例两个缓存失效的场景:

  1. 更新操作导致缓存失效
  2. 手动清除缓存

我们使用 MyBatis 来配置和执行 SQL 查询,并观察缓存的效果。首先是 MyBatis 的 XML 映射文件 UserMapper.xml,定义了 User 对象的 SQL 映射。

<!-- UserMapper.xml -->
<mapper namespace="com.example.UserMapper">
    <select id="getUserById" resultType="com.example.User">
        SELECT * FROM user WHERE id = #{id}
    </select>
</mapper

然后是对应的 Java 接口 UserMapper.java,定义了查询用户信息的方法。

// UserMapper.java
import com.example.User;

public interface UserMapper {
    User getUserById(int id);
}

接着,我们编写测试代码来演示缓存失效的两种情况:

import com.example.User;
import com.example.UserMapper;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.IOException;
import java.io.Reader;

public class Main {
    public static void main(String[] args) throws IOException {
        Reader reader = Resources.getResourceAsReader("mybatis-config.xml");
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
        SqlSession sqlSession = sqlSessionFactory.openSession();

        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);

        // 第一次查询,会发送实际的 SQL 查询请求
        User user1 = userMapper.getUserById(1);
        System.out.println(user1);

        // 第二次查询,会从本地缓存中获取,不会发送实际的 SQL 查询请求
        User user2 = userMapper.getUserById(1);
        System.out.println(user2);

        // 更新操作导致缓存失效
        User newUser = new User();
        newUser.setId(1);
        newUser.setName("Updated Name");
        userMapper.updateUser(newUser);
        sqlSession.commit();

        // 更新操作导致缓存失效,再次查询会发送实际的 SQL 查询请求
        User user3 = userMapper.getUserById(1);
        System.out.println(user3);

        // 手动清除缓存
        sqlSession.clearCache();

        // 手动清除缓存,再次查询会发送实际的 SQL 查询请求
        User user4 = userMapper.getUserById(1);
        System.out.println(user4);

        sqlSession.close();
    }
}

在这个示例中,我们首先创建了一个 SqlSessionFactory 实例,并使用它来打开一个 SqlSession。然后,我们获取了 UserMapper 接口的实现,执行了两次查询操作,观察到了本地缓存的效果。接着,我们模拟了两种缓存失效的情况:

  1. 更新操作导致缓存失效:当执行更新操作后,之前缓存的查询结果会失效,需要重新查询数据库。
  2. 手动清除缓存:通过手动调用 sqlSession.clearCache() 方法,可以清除本地缓存,导致之后的查询重新发送 SQL 查询请求。

通过这个示例,我们详细讲解了 MyBatis 的缓存机制,并演示了两种缓存失效的情况。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

张有财Java成长之路

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值