
MyBatis框架-缓存机制
MyBatis是基于JDBC的封装,使数据库操作更加便捷。在MyBatis中引入缓存,可以更好的节省资源,提高效率。
·
MyBatis框架-缓存机制
MyBatis是基于JDBC的封装,使数据库操作更加便捷。MyBatis除了对JDBC操作步骤封装之外,也对其性能进行了优化:
- 在MyBatis中引入缓存机制,用于提升Mybatis检索效率
1. 缓存的工作原理
缓存:用于存储数据的内存
2. MyBatis缓存
Mybatis缓存分为一级缓存和二级缓存
2.1 一级缓存
一级缓存,也叫做SqlSession级缓存,为每个sqlSession对象单独分配的缓存内存,无需手动开启,可直接使用;多个SqlSession的缓存是不共享的。
特性:
- 如果多次查询使用的是同一个SqlSession对象,则第一次查询之后会存放到缓存,后续的查询则直接访问缓存中的存储数据;
- 如果第一次查询完成之后,对查询出来的
对象
进行修改(此修改影响缓存),第二次查询的数据就是缓存中修改后的数据,造成第二次查询的结果与数据库不一致;- 当我们进行查询操作时,需要跳过缓存直接查询数据库时,可以使用sqlSession.clearCache() 来清空当前sqlSession的缓存;
- 如果第一次查询之后,第二次查询之前,使用sqlSession执行了修改操作,此操作会使第一次查询的缓存数据失效,因此第二次查询会再次访问数据库进行查询。
2.2 二级缓存
二级缓存:SqlSessionFactory级缓存,通过同一个Factory对象获取的sqlSession可以共享缓存;在应用服务器中SqlSessionFactory是单例的,因此我们二级缓存可以实现全局共享。
一级缓存其共享范围就是一个SqlSession内部,如果多个SqlSession之间需要共享缓存,则需要使用到二级缓存,其共享范围为Namespace。开启二级缓存后,会使用CachingExecutor装饰Executor,进入一级缓存的查询流程前,先在CachingExecutor进行二级缓存的查询。
特性:
- 二级缓存默认没有开启,需要在mybatis-config.xml中的settings标签开启
- 二级缓存只能缓存实现序列化接口的对象;
- 序列化:将数据从内存存储到硬盘。(注意:类的属性为实例或者有父类都需要序列化,即为级联序列化,避免数据部分丢失)
- 反序列化:将数据从硬盘存储到内存。
- Mybatis默认关闭二级缓存。
- 作用粒度:相同namespace下所有sql语句共享缓存,即:支持不同sqlSession共享缓存。
- 数据写入时机:sqlSession.close(),即:sql会话关闭后,统一将当前namespace下的一级缓存写入二级缓存。节约I/O,提高I/O性能。
- 二级缓存清理:与清理一级缓存相同,执行commit()方法,但是仅仅针对增删改commit,查询commit无法触发清理。
- 关闭单个查询语句二级缓存方式:XXmapper.xml sql语句设置关闭useCache=“false”。
2.2.1开启二级缓存
- 配置setting,即:
<setting name="cacheEnabled" value="true"/>
- 指定namespace配置开启,即:
<cache/>
2.2.2 二级缓存策略
<!--创建了FIFO策略(first in first out);30秒刷新一次缓存;最多存储360个对象缓存;缓存对象是只读属性-->
<cache eviction="FIFO" flushInterval="30000" size="360" readOnly="true"/>
- eviction:缓存的回收策略
- flushInterval:时间间隔,单位是毫秒
- size:引用数目,内存大就多配置。默认值是 1024
- readOnly:true-只读
缓存四大策略:
- LRU – 最近最少使用的:移除最长时间不被使用的对象,默认
- FIFO – 先进先出:按对象进入缓存的顺序来移除它们
- SOFT – 软引用:移除基于垃圾回收器状态和软引用规则的对象
- WEAK – 弱引用:更积极地移除基于垃圾收集器状态和弱引用规则的对象
2.4 一二级缓存对比
对比项 | 一级缓存 | 二级缓存 |
---|---|---|
作用范围 | sqlSession | nameSpace |
开启方式 | 默认开启 | 手动开启 |
存储方式 | 内存 | 硬盘 |
清理时机 | 增删改查commit() | 增删改commit() |
存储时机 | 执行完sql | sqlSession.close() |
关闭方式 | 设置statement模式 | 不启用->全局关闭 设置useCache=“false”->单个sql查询关闭 |
脏数据场景 | 多线程并发场景,不同线程不同sqlSession更新数据 | 分布式多实例机器部署namespace不规范编写其他表sql |
更多推荐
所有评论(0)