Mybatis缓存

本文详细介绍了Mybatis的一级缓存和二级缓存机制。一级缓存默认开启,作用于单个SqlSession会话,而二级缓存是基于namespace级别的全局缓存。当遇到增删改操作时,一级缓存会被清除。通过实例展示了二级缓存如何在不同会话间共享数据,降低了数据库查询负担,提高了系统响应速度。
摘要由CSDN通过智能技术生成

Mybatis缓存

我们都知道,在进行频繁的数据库查询操作时,比较耗费资源。这时,缓存的重要性不言而喻。在第一次查询时,就将查询结果放入缓存,后续相同的查询操作,直接从缓存查找对应数据即可。Mybatis则提供了两级缓存机制。分别是一级缓存(作用于一个sqlsession会话,默认开启)和二级缓存(基于namespace级别的缓存,一个命名空间对应一个二级缓存)


一、一级缓存

一级缓存默认开启,它作用于一个sqlsession会话,也就是从建立sqlsession连接至——连接关闭。比如我两次通过同一个用户id查询用,代码和测试如下:

@Test
    public void findUserById(){
       SqlSession sqlSession = MybatisUtils.getSqlSession();
       UserDAO userDAO = sqlSession.getMapper(UserDAO.class);
       User user = userDAO.findUserById(1);
       
       User user1 = userDAO.findUserById(1);
       System.out.println(user == user1);
       sqlSession.close();
    }

在mybatis配置文件中已经使用默认日志STDOUT_LOGGING。结果如下
在这里插入图片描述

可以看出两次查询只对数据库做了一次查询,即第二次从缓存查得结果。下面我们进一步看一下一级缓存的失效情况。

缓存失效情况

根据mybatis官方文档,一级缓存只限于前后查询相同的数据,若前后查询过程中出现增删改操作,即使不是作用于查询对象,也会使得缓存被清除。以更新操作为例,代码如下:

 @Test
    public void findUserById(){
       SqlSession sqlSession = MybatisUtils.getSqlSession();
       UserDAO userDAO = sqlSession.getMapper(UserDAO.class);
       User user = userDAO.findUserById(1);
       
       userDAO.updateUser(new User(2,"xiao","1231"));

       User user1 = userDAO.findUserById(1);
       System.out.println(user == user1);
       sqlSession.close();
    }

在两次查询操作之间更新id为2的用户信息,结果如下:
在这里插入图片描述
可以看出,一共执行了3条SQL,即中间的更新操作将一级缓存刷新,导致第二次查询操作需要重新从数据库读取数据。

二、二级缓存

二级缓存也叫全局缓存,由于一级缓存作用域太低,从而诞生了二级缓存。它是基于namespace级别的缓存,一个命名空间对应一个二级缓存默认开启。下面进行测试

工作机制

  1. 一个会话查询一条数据,数据就被放入一级缓存
  2. 如果当前会话关闭,一级缓存中数据就被清除,但我们希望关闭时,将数据放入二级缓存。
  3. 新会话查询信息,就可以先从二级缓存中查找。
  4. 其中不同的mapper查询的数据会放在各自的缓存(map)中。

步骤

显示的在mybatis配置文件下的settings中进行配置,提高可读性

<setting name="cacheEnabled" value="true"/>

随后在*mapper.xml下增加标签,表示使用二级缓存。当然也能在select语句中使用useCache选项。

测试

新建两个会话(基于同一个mapper查询),查看第二个会话在第一个会话关闭后,能否从二级缓存中获得第一个会话查询的数据。
代码如下:

 @Test
    public void findUserById(){
       SqlSession sqlSession1 = MybatisUtils.getSqlSession();
       SqlSession sqlSession2 = MybatisUtils.getSqlSession();

       UserDAO userDAO1 = sqlSession1.getMapper(UserDAO.class);
       User user1 = userDAO1.findUserById(1);
       sqlSession1.close();

       UserDAO userDAO2 = sqlSession2.getMapper(UserDAO.class);
       User user2 = userDAO2.findUserById(1);
       System.out.println(user1 == user2);
       sqlSession2.close();
    }

测试结果如下:
在这里插入图片描述
可以看出,只执行一次SQL,即第二次已经通过二级缓存成功获取到数据。

缓存顺序

mybatis中数据查询策略

  1. 先查询二级缓存
  2. 再查询一级缓存
  3. 最后查询数据库

总结

合理使用二级缓存,降低数据库负担,在实际项目中也能提高系统响应速度。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值