橘子学Mybatis09之Mybatis关于二级缓存的使用

本文详细介绍了MyBatis中的一级和二级缓存开启方式、源码设计以及查询时机。重点讲解了CachingExecutor作为装饰器如何增强查询性能,以及缓存的创建、存储和使用过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前面我们说了一级缓存,但是实际上我们说那玩意其实不咋实用。于是既然设计了缓存体系,就不可能弄个不实用的给人们。所以这里就引出二级全局缓存。
全局缓存就是无视sqlSession,你可以理解为一个分布式的缓存。作为全局的访问。

一、二级缓存

1、开启方式

二级缓存默认是不开启的,所以他需要你手动去开启。开启方式需要满足下面四个条件。

1、需要在核心配置文件,我的是sqlMapConfig.xml中指定,在<setting 中的配置。其实最新版mybatis这个条件其实可以不用,因为在configuration中的cache默认就是true。
2、需要在mapper.xml中引进二级缓存Cache的标签。
3、需要在查询标签<select中引入useCache属性打开。,其实这个也是可以不用配置的,我们这里就先配置上。
4、需要有事务的存在。

第一步和第三步可以不写。
于是我们就来操作验证一下,我们首先在UserMapper.xml中配置第二步和第三步。

<mapper namespace="com.yx.dao.IUserDao">

  <cache></cache>

  <select id="findAll" resultType="com.yx.domain.User" useCache="true">
          SELECT * FROM `user`
  </select>
</mapper>

然后在代码中开启事务的提交。

@Test
public void test3() throws IOException {
   
 // 读取配置文件转化为流
 InputStream inputStream = Resources.getResourceAsStream("sqlMapConfig.xml");
 SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);
 SqlSession sqlSession = factory.openSession();
 SqlSession sqlSession2 = factory.openSession();
 //这⾥不调⽤SqlSession的api,⽽是获得了接⼝对象,调⽤接⼝中的⽅法。使用JDK动态代理产生代理对象
 IUserDao userDao = sqlSession.getMapper(IUserDao.class);
 IUserDao userDao2 = sqlSession2.getMapper(IUserDao.class);
 // 第一次执行查询
 List<User> userList = userDao.findAll();
 userList.forEach(user -> {
   
   System.out.println(user.toString());
 });
 // 事务提交
 sqlSession.commit();

 System.out.println("*************************************************");

 // 第二次执行相同的查询
 List<User> userList2 = userDao2.findAll();
 userList2.forEach(user -> {
   
   System.out.println(user.toString());
 });
 // 事务提交
 sqlSession2.commit();
}

我们看下输出:

Opening JDBC Connection
Loading class `com.mysql.jdbc.Driver'. This is deprecated. The new driver class is `com.mysql.cj.jdbc.Driver'. The driver is automatically registered via the SPI and manual loading of the driver class is generally unnecessary.
Created connection 203819996.
Setting autocommit to false on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@c260bdc]
==>  Preparing: SELECT * FROM `user`
==> Parameters: 
<==    Columns: id, name
<==        Row: 1, 张飞
<==        Row: 2, 关羽
<==        Row: 3, 孙权
<==      Total: 3
User{id=1, username='张飞'}
User{id=2, username='关羽'}
User{id=3, username='孙权'}
*************************************************
As you are using functionality that deserializes object streams, it is recommended to define the JEP-290 serial filter. Please refer to https://docs.oracle.com/pls/topic/lookup?ctx=javase15&id=GUID-8296D8E8-2B93-4B9A-856E-0A65AF9B8C66
Cache Hit Ratio [com.yx.dao.IUserDao]: 0.5// 缓存命中
User{id=1, username='张飞'}
User{id=2, username='关羽'}
User{id=3, username='孙权'}

我们看到缓存被命中了,第二次新的sqlsession中并没有执行sql,也没有创建连接,可见mybat

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值