05. Mybatis缓存问题

一 Mybatis两种缓存的解释

1. 一级缓存

在学习一级缓存之前,我们先了解一下SqlSession

SqlSession是对Connection的一层封装

如果要显式使用SqlSession,先使用输入流InputStream读取Mybatis的配置文件;再通过SqlSessionFactoryBuilder加载流,然后获取到SqlSessionFactory;通过SqlSessionFactory获取到SqlSession

		String resource = "mybatis-config.xml";
        // 使用Resources工具从类加载路径下加载指定文件
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
		SqlSession sqlSession = sqlSessionFactory.openSession();

一级缓存的作用域有两种:session(默认)和statment,可通过设置local-cache-scope 的值来切换,默认为session,SqlSession之间互相隔离;二者的区别在于session会将缓存作用于同一个sqlSesson,而statment仅针对一次查询,所以,local-cache-scope: statment可以理解为关闭一级缓存

一级缓存命中的条件是

  1. 同一个SqlSession
  2. 同一个Mapper中的同一个方法
  3. sql完全相同

这三个条件缺一不可

通常我们使用的MVC设计模式,分为三层架构,如果我们在Service调用Mapper,在不加事务的情况下每次调用都会create一个新的SqlSession,也就是说这种情况下缓存是不会生效的;如果加了事务,这种情况下就会复用创建的SqlSession,如果符合条件就会命中缓存

2. 二级缓存

二级缓存的作用域是一个命名空间,也就是一个mapper.xml中的范围,与SqlSession无关,只要是在一个命名空间内的相同的sql都可以命中缓存,可以被SqlSession共享

二级缓存命中的条件是

  1. 同一个命名空间内
  2. 同一个Mapper中的同一个方法
  3. sql完全相同

二 两种缓存的使用方式

1. 一级使用方式

1.1 开启

默认开启,无需操作

1.2 刷新

  1. 在一个SqlSession中如果执行了CUD操作,就会刷新一级缓存
  2. 开启flushCache=“true”,在xml的statement标签中标注

1.3 关闭

全局关闭:local-cache-scope: statment

关闭单个:在statement标签中flushcache=true

2. 二级使用方式

2.1 开启

默认开启,但是需要在命名空间中加上下面的配置后才会生效

<cache  eviction="FIFO" flushInterval="60000"  size="512" readOnly="true"/>

2.2 刷新

  1. 在同一命名空间中的CUD就会刷新二级缓存
  2. 达到了flushInterval超时时间就会刷新二级缓存

2.3 关闭

全局关闭:直接设置cache-enabled: true或者在命名空间中不要加标签

单个关闭:在statement标签中设置useCache=false

三 总结

Mybatis获取数据的顺序优先级:二级缓存>一级缓存>数据库

两种缓存都会造成脏读的问题,主要原因:

  1. 一级缓存SqlSession之间是互相隔离的,无法感知到别人的变化(刷新)

    解决办法:减小SqlSession作用域或者关闭对应的一级缓存

  2. 二级缓存命名空间之间互相隔离,无法感知到别人的变化(刷新)

    解决办法:引用别的命名空间,使他们在同一个作用域中,或者关闭对应的二级缓存

如果不加事务,每次查询之后就会立即commit,这也是不加事务一级缓存无法生效的原因,因为每次查询都是一个新的SqlSession

同时,如果事务的隔离级别是REQUIRES_NEW(开启新的事务),一级缓存也无法生效

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值