二級緩存的原理
-
MyBatis 二級緩存的原理是什么?
- 二級緩存的原理和一級緩存一樣,第一次查詢會將數據放到 緩存 中,然后第二次查詢直接去緩存讀取。
- 但是一級緩存是基于 SqlSession 的,二級緩存是基于 mapper 的 namespace 的。
- 也就是說,多個 SqlSession 可以共享同一個二級緩存區域。如果兩個 mapper 的 namespace 相同,那么即使是兩個 mapper,這兩個 mapper 執行 sql 查詢的數據也將保存在相同的二級緩存區域中。
??
如何使用二級緩存
注意:User 需要實現序列化接口。
開啟二級緩存
和一級緩存不一樣,二級緩存需要手動開啟。
首先在全局配置文件 sqlMapConfig.xml 中加入如下代碼
<settings><!-- 開啟二級緩存 --><setting name="cacheEnabled" value="true"/>
</settings>
然后在 UserMapper.xml 中開啟二級緩存。
<!-- 開啟二級緩存 -->
<cache />
如果是使用注解方式,在 IUserMapper
? 上寫上注解 @CacheNamespace
?
@CacheNamespace
public interface IUserMapper {
}
測試代碼
public class SecondCacheTest {private SqlSessionFactory sqlSessionFactory;@Beforepublic void before() throws Exception {InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);}@Testpublic void secondLevelCache() {SqlSession sqlSession1 = sqlSessionFactory.openSession();SqlSession sqlSession2 = sqlSessionFactory.openSession();IUserMapper userMapper1 = sqlSession1.getMapper(IUserMapper.class);IUserMapper userMapper2 = sqlSession2.getMapper(IUserMapper.class);User user1 = userMapper1.findUserById(1);// 清空一級緩存sqlSession1.close();User user2 = userMapper2.findUserById(1);System.out.println(user1 == user2);}
}
效果如下
Setting autocommit to false on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@56528192]
==> Preparing: select * from user where id=?
==> Parameters: 1(Integer)
<== Columns: id, username, password, birthday
<== Row: 1, lucy, 123, 2019-12-12
<== Total: 1
Resetting autocommit to true on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@56528192]
Closing JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@56528192]
Returned connection 1448247698 to pool.
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.terwergreen.mapper.IUserMapper]: 0.5
false
可以看到,兩次請求,只有第一次輸出了 sql , 并且輸出了緩存命中率是 0.5 。
useCache 和 flushCache
-
useCache 用來設置是否禁用二級緩存。在 statement 中設置 useCache="false" 可以禁用當前 select 語句的 二級緩存
-
<select id="selectUserByUserId" useCache="false" resultType="space.terwer.pojo.User" parameterType="int">select * from user where id=#{id} </select>
-
設置 statement 的 flushCache="true" 即 刷新緩存 ,默認情況下就是 true。因為一般不設置,默認即可
-
注解方式的使用
/*** 根據ID查詢用戶** @param id* @return*/ @Options(useCache = false, flushCache = Options.FlushCachePolicy.TRUE) @Select("select * from user where id=#{id}") User findUserById(Integer id);
文章更新歷史
2024/05/15 同步文章到其他平臺
2022-12-25 feat: 初稿
?