《艾爾登法環》法力斯的製作筆記獲取位置 法力斯筆記在哪
阿新 • • 發佈:2022-03-23
引言
什麼是快取:
存在於記憶體中的臨時資料。
為什麼使用快取:
減少和資料庫的互動次數,提高執行效率。
什麼樣的資料能用快取,什麼資料不能使用:
適用於快取:
經常查詢並且不經常改變的
資料的正確與否對最終結果影響不大(因為快取代表著會與資料庫資料不同)
不適用於快取:
經常改變的資料
資料的正確與否對最終結果影響很大的
例如:商品的庫存,銀行的匯率,股市的牌價
一級快取
定義
mybatis中SqlSession物件的快取。當我們執行查詢之後,查詢的結果會同時存入到SqlSession為我們提供的一塊區域中。該區域的結構是一個Map。當我們再次查詢同樣的資料,mybatis會先去SqlSession中檢視是否有,有的話直接拿出來用。
當SqlSession物件消失時,一級快取也就消失了。
一級快取演示
@Test
public void testFirstLevelCache(){
User user1 = dao.findById(41);
System.out.println(user1);
User user2 = dao.findById(41);
System.out.println(user2);
System.out.println(user1 == user2);
}
只進行一次查詢,第二次查詢使用的是一級快取,獲取的物件也是相同地址的。
@Test public void testFirstLevelCache(){ User user1 = dao.findById(41); System.out.println(user1); session.close(); session = factory.openSession(); dao = session.getMapper(UserDao.class); /**可用:session.clearCache(); 清空快取**/ User user2 = dao.findById(41); System.out.println(user2); System.out.println(user1 == user2); }
執行了兩次查詢,物件地址不相同,證明第二個user是再new一次的
如果一級快取中的資料域資料庫不一致如何做到同步
更新辦法
<update id="updateUser" parameterType="user"> update user set id = #{id} <if test="username != null and username != ''"> ,username = #{username} </if> <if test="address != null and address != ''"> ,address = #{address} </if> <if test="sex != null and sex != ''"> ,sex = #{sex} </if> <if test="birthday != null"> ,birthday = #{birthday} </if> where id = #{id} </update>
演示
@Test
public void testFirstLevelCache(){
User user1 = dao.findById(41);
System.out.println(user1);
User user = new User();
user.setId(41);
user.setUsername("clear cache");
user.setSex("女");
dao.updateUser(user);
User user2 = dao.findById(41);
System.out.println(user2);
System.out.println(user1 == user2);
}
可以看出更新後,就不會從一級快取中查詢,而是進行一次新的查詢
原因
當呼叫SqlSession的修改,新增,刪除,commit(),close()等方法時,就會清空一級快取
二級快取
定義
指的是Mybatis中SqlSessionFactory物件的快取。由同一個SqlSessionFactory物件建立的SqlSession共享其快取。
二級快取的使用步驟
第一步:讓mybatis框架支援二級快取(在SqlMapConfig.xml中配置)
<settings>
<setting name="cacheEnabled" value="true"/>
</settings>
第二步:讓當前的對映檔案支援二級快取(在UserDao.xml中配置)
<!--開啟user支援二級快取-->
<cache></cache>
第三步:讓當前的操作支援二級快取(在select標籤中配置)
<!--根據id查詢單個使用者-->
<select id="findById" resultType="com.czy.domain.User" parameterType="INT" useCache="true">
select * from user where id = #{id};
</select>
測試
@Test
public void testSecondLevelCache(){
SqlSession session1 = factory.openSession();
UserDao dao1 = session1.getMapper(UserDao.class);
User user1 = dao1.findById(41);
System.out.println(user1);
session1.close(); //一級快取消失
SqlSession session2 = factory.openSession();
UserDao dao2 = session2.getMapper(UserDao.class);
User user2 = dao2.findById(41);
System.out.println(user2);
session2.close();
System.out.println(user1 == user2);
}
只進行了一次查詢,第二次直接呼叫快取,由於儲存的是資料不是物件,故比較結果為false