Mybatis-缓存机制

简介: 像大多数的持久化框架一样,Mybatis也提供了缓存策略,通过缓存策略来减少数据库的查询次数,从而提高性能。 Mybatis中缓存分为一级缓存,二级缓存。Mybatis一级缓存Mybatis的一级缓存默认是开启的,而且是不能关闭的。一级缓存是指SqlSession级别的缓存,当在同一个SqlSession中进行相同的SQL语句查询时,第二次以后的查询不会从数据库查询,而是直接从缓存中获取,一级缓存最多缓存1024条SQL。

像大多数的持久化框架一样,Mybatis也提供了缓存策略,通过缓存策略来减少数据库的查询次数,从而提高性能。 Mybatis中缓存分为一级缓存,二级缓存。

Mybatis一级缓存

Mybatis的一级缓存默认是开启的,而且是不能关闭的。一级缓存是指SqlSession级别的缓存,当在同一个SqlSession中进行相同的SQL语句查询时,第二次以后的查询不会从数据库查询,而是直接从缓存中获取,一级缓存最多缓存1024条SQL。

一级缓存的原理(SqlSession级别)

第一次发出一个查询sql,sql查询结果写入sqlsession的一级缓存中,缓存使用的数据结构是一个map、

key:MapperID+offset+limit+Sql+所有的入参

value:用户信息

同一个sqlsession再次发出相同的sql,就从缓存中取出数据。如果两次中间出现commit操作(修改、添加、删除),本sqlsession中的一级缓存区域全部清空,下次再去缓存中查询不到之前的数据,所以要从数据库中查询,从数据库查询到再写入缓存中。
image.png

代码验证:

/**
     * 测试一级缓存的存在
     * @throws Exception
     */
    @Test
    public void testFirstCache() throws Exception {
        //1、读取配置文件
        InputStream in=Resources.getResourceAsStream("SqlMapConfig.xml");
        //2、创建SqlSessionFactory的构建者对象
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        //3、使用构建者创建工厂对象SqlSessionFactory
        SqlSessionFactory factory= builder.build(in);
        //4、使用SqlSessionFactory创建SqlSession
        SqlSession session=factory.openSession();
        //5、使用SqlSession创建dao接口的代理对象
        UserMapper userDao =session.getMapper(UserMapper.class);
        //6、使用代理对象执行查询方法
        User user =userDao.findById(2);
        System.out.println(user);
        User user1=userDao.findById(2);
        System.out.println(user1);
        //7、释放资源
        session.close();
        try {
            in.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

Mybatis二级缓存

二级缓存是mapper映射级别的缓存,多个sqlsession去操作同一个Mapper映射的sql语句,多个SqlSession可以共用二级缓存,二级缓存是跨SqlSession的。
image.png

第一步:在SqlMapConfig.xml文件开启二级缓存

<settings> 
    <!-- 开启二级缓存的支持 -->
     <setting name="cacheEnabled" value="true"/> 
</settings>

因为cacheEnabled的取值默认就为true,所以这一步可以省略不配置。为true代表开启二级缓存;为false代表不开启二级缓存。

第二步:配置相关的Mapper映射文件

标签表示当前这个mapper映射将使用二级缓存,区分的标准就看mapper的namespace值。

<?xml version="1.0" encoding="UTF-8"?> 
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> 
<mapper namespace="com.itheima.dao.IUserDao"> 
      <!-- 开启二级缓存的支持 --> 
      <cache></cache> 
</mapper>

第三步:配置statement上面的useCache属性

<!-- 根据id查询 -->
 <select id="findById" resultType="user" parameterType="int" useCache="true"> 
    select * from user where id = #{uid} 
</select>

将UserDao.xml映射文件中的标签中设置useCache=”true”代表当前这个statement要使用二级缓存,如果不使用二级缓存可以设置为false。

注意:针对每次查询都需要最新的数据sql,要设置成useCache=false,禁用二级缓存。

代码验证:

  /**
     * 测试二级缓存的存在
     * @throws Exception
     */
    @Test
    public void testSecondCache() throws Exception {
        //1、读取配置文件
        InputStream in=Resources.getResourceAsStream("SqlMapConfig.xml");
        //2、创建SqlSessionFactory的构建者对象
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        //3、使用构建者创建工厂对象SqlSessionFactory
        SqlSessionFactory factory= builder.build(in);
        //4、使用SqlSessionFactory创建SqlSession
        SqlSession session1=factory.openSession();
        //5、使用SqlSession创建dao接口的代理对象
        UserMapper userDao =session1.getMapper(UserMapper.class);
        //6、使用代理对象执行查询方法
        User user =userDao.findById(2);
        System.out.println(user);
        //7、释放资源
        session1.close();
        SqlSession session2=factory.openSession();
        UserMapper userDao2=session2.getMapper(UserMapper.class);
        User user2=userDao2.findById(2);
        System.out.println(user2);
        session2.close();
 
        System.out.println(user==user2);
        in.close();
    }

经过上面的测试,我们发现执行了两次查询,并且在执行第一次查询后,我们关闭了一级缓存,再去执行第二次查询时,我们发现并没有对数据库发出sql语句,所以此时数据来源就是我们所说的二级缓存。

目录
相关文章
|
1天前
|
存储 缓存 前端开发
HTTP的缓存机制是什么?
HTTP的缓存机制是什么?
33 1
|
1天前
|
存储 缓存 运维
【Docker 专栏】Docker 镜像的分层存储与缓存机制
【5月更文挑战第8天】Docker 镜像采用分层存储,减少空间占用并提升构建效率。每个镜像由多个层组成,共享基础层(如 Ubuntu)和应用层。缓存机制加速构建和运行,通过检查已有层来避免重复操作。有效管理缓存,如清理无用缓存和控制大小,可优化性能。分层和缓存带来资源高效利用、快速构建和灵活管理,但也面临缓存失效和层管理挑战。理解这一机制对开发者和运维至关重要。
【Docker 专栏】Docker 镜像的分层存储与缓存机制
|
1天前
|
缓存 NoSQL Java
17:缓存机制-Java Spring
17:缓存机制-Java Spring
41 5
|
1天前
|
存储 缓存 自然语言处理
深入PHP内核:探索Opcode缓存机制
【5月更文挑战第1天】 在动态语言如PHP的执行过程中,每次脚本被请求时都需要经过一系列复杂的解析和编译步骤。为了优化这一过程并提高性能,PHP引入了Opcode缓存机制。本文将详细探讨Opcode的概念、作用以及它如何显著提升PHP应用的执行效率。我们将从缓存原理出发,分析几种常见的Opcode缓存工具,并通过实例说明如何在实际项目中实现和优化缓存策略。
|
1天前
|
缓存 NoSQL PHP
【PHP开发专栏】PHP缓存机制与实现
【4月更文挑战第29天】本文介绍了PHP缓存的基本概念、策略及实现方式。PHP缓存包括应用缓存、Web服务器缓存、数据库缓存和分布式缓存,常见策略有缓存预热、更新和懒加载。PHP的缓存实现包括文件缓存、APC、OPcache、Memcached和Redis。最佳实践包括缓存热点数据、控制粒度、设置失效策略、保证一致性和确保安全性。文中还提供了一个新闻列表和详情页的缓存实战示例,帮助开发者理解如何在实际项目中应用缓存。
|
1天前
|
缓存 流计算
缓存命中率和过期机制的一般思路
【4月更文挑战第20天】缓存命中率是评估缓存效果的关键,目标是达到90%以上,但某些频繁的小请求场景可能无法实现。过期机制可采用定时删除(精确但开销大)、延迟队列(精确但有队列开销)、懒惰删除(简单但时间不精确)或定期删除(简单但性能损耗不可控)。
19 4
|
1天前
|
缓存 Linux
linux系统缓存机制
linux系统缓存机制
|
1天前
|
缓存 数据库 开发者
Django视图中的缓存机制:提升页面加载速度
【4月更文挑战第15天】本文介绍了Django的缓存机制在提升页面加载速度中的作用。Django提供视图缓存和片段缓存,通过`cache_page`装饰器和`CacheMixin`实现视图级别的缓存,使用`{% cache %}`模板标签实现页面片段缓存。开发者可选择不同的缓存后端,并在设置中配置缓存参数。同时,注意合理控制缓存粒度、及时更新和管理缓存,以优化用户体验和网站性能。
|
1天前
|
XML 缓存 Java
MyBatis二级缓存解密:深入探究缓存机制与应用场景
MyBatis二级缓存解密:深入探究缓存机制与应用场景
76 2
MyBatis二级缓存解密:深入探究缓存机制与应用场景
|
1天前
|
存储 缓存 算法
深入探究LRU缓存机制:优化内存利用与提升性能
深入探究LRU缓存机制:优化内存利用与提升性能
219 1