当前位置: 首页 > article >正文

JAVA:MyBatis 缓存机制详解的技术指南

1、简述

MyBatis是Java开发中常用的持久层框架之一,通过面向对象的方式操作数据库。为了提高系统性能,MyBatis提供了两级缓存机制:一级缓存(本地缓存)和二级缓存(全局缓存)。本文将详细讲解MyBatis缓存机制的使用原理、配置方法,并通过示例展示如何合理地使用缓存优化数据访问效率。

在这里插入图片描述

2、基础原理

2.1 一级缓存
  • 作用范围:一级缓存是基于SqlSession级别的缓存,即在同一个SqlSession中执行的相同SQL语句将会从缓存中获取结果,而不会再去查询数据库。
  • 存储方式:一级缓存的默认存储机制是基于HashMap实现的。
  • 特点:默认开启,无法跨SqlSession共享数据,查询范围有限。
2.2 二级缓存
  • 作用范围:二级缓存是基于Mapper级别的缓存,即同一个命名空间的Mapper都可以共享二级缓存。
  • 存储方式:MyBatis默认使用PerpetualCache作为二级缓存,使用HashMap进行存储。
  • 特点:二级缓存是可选的,需要在配置文件中开启,支持多个SqlSession共享同一数据,能够有效减少数据库查询次数。

3、一级缓存的使用

一级缓存默认开启,无需额外配置。当执行同一查询时,MyBatis会先检查一级缓存,若存在结果则直接返回缓存数据,否则才会执行SQL查询数据库。

import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import com.example.mapper.UserMapper;
import com.example.model.User;

public class MyBatisCacheDemo {

    public static void main(String[] args) {
        SqlSessionFactory sqlSessionFactory = MyBatisUtil.getSqlSessionFactory();

        try (SqlSession session = sqlSessionFactory.openSession()) {
            UserMapper userMapper = session.getMapper(UserMapper.class);

            // 第一次查询
            User user1 = userMapper.selectUserById(1);
            System.out.println("第一次查询:" + user1);

            // 第二次查询,触发一级缓存
            User user2 = userMapper.selectUserById(1);
            System.out.println("第二次查询(来自缓存):" + user2);

            // 判断是否为同一对象
            System.out.println("是否为同一对象:" + (user1 == user2));  // true
        }
    }
}

注意:如果执行了session.commit()、session.close()、session.clearCache()等操作,一级缓存将会失效。

4、二级缓存的配置与使用

MyBatis默认关闭二级缓存,需要在mybatis-config.xml或Mapper映射文件中开启。

4.1 在全局配置文件中开启二级缓存

在mybatis-config.xml中增加true,如:

<configuration>
    <settings>
        <setting name="cacheEnabled" value="true"/>
    </settings>
</configuration>
4.2 在Mapper XML文件中配置二级缓存

在具体的Mapper文件中加入标签来启用二级缓存。

<mapper namespace="com.example.mapper.UserMapper">
    <cache/>
    
    <select id="selectUserById" parameterType="int" resultType="com.example.model.User">
        SELECT * FROM user WHERE id = #{id}
    </select>
</mapper>
4.3 使用二级缓存示例
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import com.example.mapper.UserMapper;
import com.example.model.User;

public class MyBatisCacheDemo {

    public static void main(String[] args) {
        SqlSessionFactory sqlSessionFactory = MyBatisUtil.getSqlSessionFactory();

        // 第一次查询,开启第一个SqlSession
        try (SqlSession session1 = sqlSessionFactory.openSession()) {
            UserMapper userMapper1 = session1.getMapper(UserMapper.class);
            User user1 = userMapper1.selectUserById(1);
            System.out.println("第一次查询:" + user1);
        } // SqlSession关闭,触发二级缓存存储

        // 第二次查询,开启新的SqlSession
        try (SqlSession session2 = sqlSessionFactory.openSession()) {
            UserMapper userMapper2 = session2.getMapper(UserMapper.class);
            User user2 = userMapper2.selectUserById(1);
            System.out.println("第二次查询(来自二级缓存):" + user2);

            // 判断是否为同一对象
            System.out.println("是否为同一对象:" + (user1 == user2));  // true
        }
    }
}

5、缓存失效的场景

在以下情况下,MyBatis的缓存将会失效:

  • 增删改操作:每当执行INSERT、UPDATE或DELETE操作后,一级缓存和二级缓存都会失效。
  • 手动清空缓存:可以通过SqlSession.clearCache()方法手动清空一级缓存。
  • 不同SqlSession:一级缓存仅作用于当前SqlSession,不同SqlSession之间无法共享一级缓存。
  • 其他影响因素:MyBatis中mapper.xml文件中的flushCache配置项等也会影响缓存策略。

缓存的优缺点分析:

  • 优点
    提升性能:缓存机制减少了数据库的交互次数,提升了查询效率。
    简化数据共享:特别是二级缓存,多个SqlSession可以共享数据,适合不经常变动的数据。
  • 缺点
    缓存不一致:数据库数据变动后,可能会造成缓存数据不一致的问题。
    占用内存:大量的数据缓存可能会导致内存占用过高。
    适用场景有限:频繁变动的数据不适合缓存。

6、总结

MyBatis的缓存机制是一种有效的数据访问优化方案。通过一级缓存和二级缓存,开发者可以显著减少数据库查询次数,提升系统的性能。在实际使用中,需要合理配置和使用缓存机制,特别是在数据变动频繁的情况下,可以适当关闭缓存或手动清空缓存,保证数据的一致性。

MyBatis缓存的使用场景建议:

  • 适用于读取频率高且修改较少的数据,如产品信息、用户基本资料等。
  • 对于频繁变更的数据,如订单、库存信息等,建议关闭缓存,以避免缓存不一致的问题。

通过合适的缓存配置和控制策略,MyBatis缓存机制可以为系统带来显著的性能提升。希望本文的示例和介绍对您在项目中使用MyBatis缓存有所帮助。


http://www.kler.cn/a/510909.html

相关文章:

  • CMD批处理命令入门(6)——常用的特殊字符
  • 2024年博客之星年度评选—创作影响力评审入围名单公布
  • CSS 合法颜色值
  • Hadoop•用Web UI查看Hadoop状态词频统计
  • 如何设置HTTPS站点防御?
  • R数据分析:有调节的中介与有中介的调节的整体介绍
  • 云计算与物联网技术的融合应用(在工业、农业、家居、医疗、环境、城市等整理较全)
  • 通俗易懂:深入String 字符串常量池的存储机制
  • MQ架构测试
  • 【Rust自学】13.1. 闭包 Pt.1:什么是闭包、如何使用闭包
  • 前端面试题-问答篇-5万字!
  • source insight多行注释怎么做 source insight可以修改注释样式吗
  • Android CustomTextField
  • 【2024年华为OD机试】(B卷,200分)- 学生方阵 (Java JS PythonC/C++)
  • Docker使用 使用Dockerfile来创建镜像
  • 【论文阅读】VCD-FL: Verifiable, collusion-resistant, and dynamic federated learning
  • python如何解析word文件格式(.docx)
  • 每日一题 405. 数字转换为十六进制数
  • .NET周刊【1月第1期 2025-01-05】
  • 如何优化爬虫以提高效率
  • vue 基础一
  • SSM基于微信小程序智慧农产品系统
  • ES6都有什么
  • K8S的探针说明和使用方式
  • RabbitMQ高级特性之发送方确认
  • 类和对象(3)——继承:extends关键字、super关键字、protected关键字、final关键字