Mybatis 的一级缓存与二级缓存

String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
//创建 SqlSessionFactory 
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
inputStream.close();
//创建 SqlSession 
SqlSession session1 = sqlSessionFactory.openSession();
TUserMapper userMapper1 = session1.getMapper(TUserMapper.class);
List<TUser> list1 = userMapper1.selectByEmailAndSex(email, sex);

一级缓存

一级缓存默认会启用,想要关闭一级缓存可以在 select 标签上配置 flushCache="true"

一级缓存存在于 SqlSession 的生命周期中,在一个 SqlSession 中查询时, MyBatis 会把以下信息通过算法生成键值

  • namespace.id
  • 指定查询结果集的范围(分页信息)
  • 查询所使用的 SQL 语句
  • 用户传递给 SQL 语句的实际参数值

将键值和查询结果存入一个 Map 对象中。如果在同一个 SqlSession 中执以上四点完全一致,那么通过算法会生成相同的键值,当 Map 中已经存在该键值时,则会返中缓存中的对象。

任何的 INSERT、 UPDATE、DELETE 操作都会清空一级缓存。

SqlSession :代表一次数据库连接,一般通过调用 Mapper 访问数据库,也可以直接发送 SQL 执行。线程不安全,要保证线程独享(方法级)。

二级缓存

二级缓存存在于 SqlSessionFactory 的生命周期中,可以理解为跨 SqlSession;缓存是以 namespace(在 Mapper.xml 文件中配置)为单位的,不同 namespace下的操作互不影响。

setting 参数 cacheEnabled,这个参数是二级缓存的全局开关,默认值是 true,如果把这个参数设置为 false,即使有后面的二级缓存配置,也不会生效。

开启二级缓存,在 Mapper.xml 文件中配置:

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

这段配置有如下意义:
Mapper.xml 中的所有 select 语句将会被缓存。
Mapper.xml 中的所有 insert,update 和 delete 语句会刷新缓存。
缓存会使用 Least Recently Used(LRU,最近最少使用的) 算法来回收。
缓存刷新间隔 60000 ms。
缓存会存储列表集合或对象(无论查询方法返回什么)的 512个引用。
缓存会被视为是只读的缓存。

使用二级缓存容易岀现脏读,建议避免使用二级缓存,在业务层使用可控制的缓存代替更好。

为什么出现脏读?
因为不同的 Mapper.xml 可以操作同一张表,而不同的 Mapper.xml 对应不同的缓存。如果用一个 Mapper.xml 对一张表进行了增删改,只会刷新自己的二级缓存,不会刷新另一个 Mapper.xml 的二级缓存。

结构图

在这里插入图片描述
图中,namespaceB 和 namespaceC 共用了一个二级缓存,因为是可以这样配置的:
<cache-ref namespace=""/>

如果两个 Mapper.xml 里面所包含的表,不会在另外的 Mapper.xml 里出现,那么它们就可以通过上面的配置,共用一个二级缓存。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值