一、Mybatis中的缓存
1、什么是缓存?
缓存就是存在于内存中的临时数据。
2、为什么要使用缓存?
为了减少和数据库交互的次数,提高执行效率。
3、适用于缓存的数据:
- 经常查询并且不经常改变的数据;
- 数据的正确与否对最终结果影响不大的。
4、不适用于缓存的数据:
- 经常改变的数据;
- 数据的正确与否对最终结果影响很大的。例如:商品的库存、银行的汇率、股市的牌价等。
二、Mybatis的一级缓存
1、一级缓存是 SqlSession 级别的缓存,只要 SqlSession 没有 flush 或 close,它就会存在。当调用 SqlSession 的修改、添加、删除、commit()、close()、clearCache() 等方法时,就会清空一级缓存。
2、一级缓存流程如下图:
- 第一次发起查询用户 id 为 1 的用户信息,Mybatis 会先去找缓存中是否有 id 为 1 的用户信息,如果没有,从数据库查询用户信息。
- 得到用户信息,将用户信息存储到一级缓存中。
- 如果 sqlSession 去执行 commit 操作(执行插入、更新、删除),那么 Mybatis 就会清空 SqlSession 中的一级缓存,这样做的目的为了让缓存中存储的是最新的信息,避免脏读。
- 第二次发起查询用户 id 为 1 的用户信息,先去找缓存中是否有 id 为 1 的用户信息,缓存中有,直接从缓存中获取用户信息。
3、注意:
- Mybatis 默认就是使用一级缓存的,不需要配置。
- 一级缓存中存放的是对象。(一级缓存其实就是 Map 结构,直接存放对象)
三、Mybatis的二级缓存
1、二级缓存是 Mapper 映射级别的缓存,多个 SqlSession 去操作同一个 Mapper 映射的 SQL 语句,多个SqlSession 可以共用二级缓存,二级缓存是 跨 SqlSession 的。
- 二级缓存流程如下图:
- 当 sqlSession1 去查询用户信息的时候,Mybatis 会将查询数据存储到二级缓存中。
- sqlSession2 去查询与 sqlSession1 相同的用户信息,Mybatis 首先会去缓存中找是否存在数据,如果存在直接从缓存中取出数据。
- 如果 sqlSession3 去执行相同 Mapper 映射下的 SQL 语句,并且执行 commit 提交,那么 Mybatis 将会清空该 Mapper 映射下的二级缓存区域的数据。
2、配置 Mybatis 的二级缓存:
- 首先在 Mybatis 配置文件中添加配置 (这一步其实可以忽略,因为默认值为 true)
<settings>
<!-- 开启缓存 -->
<setting name="cacheEnabled" value="true"/>
</settings>
- 接着在映射文件中配置
<mapper namespace="cn.ykf.mapper.UserMapper">
<!-- 使用缓存 -->
<cache/>
</mapper>
- 最后在需要使用二级缓存的操作上配置 (针对每次查询都需要最新数据的操作,要设置成 useCache="false",禁用二级缓存)
<select id="listAllUsers" resultMap="UserWithAccountsMap" useCache="true">
SELECT * FROM user
</select>
3、注意:
- 当我们使用二级缓存的时候,所缓存的类一定要实现 java.io.Serializable 接口,这样才可以使用序列化的方式来保存对象。
- 由于是序列化保存对象,所以二级缓存中存放的是数据,而不是整个对象。