<setting name="cacheEnabled" value="true" /> <!-- 二級快取的開關 --> <setting name="localCacheScope" value="STATEMENT" /> <!-- 一級快取的範圍,SESSION為開;STATEMENT為關 -->
※一級快取預設是 SESSION,表示 SqlSession;二級快取預設是 true
※SESSION 表示每個一個 Session 中的所有語句都可以共享; STATEMENT 表示只有當前的 SQL 語句的結果可以共享 (看最下面的一、二級快取)
測試類
InputStream is = null; SqlSession sqlSession = null; SqlSession sqlSession2 = null; try { is = Resources.getResourceAsStream("mybatis-config.xml"); SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is); sqlSession = factory.openSession(); DeptMapper mapper = sqlSession.getMapper(DeptMapper.class); //一級快取 Dept dept1 = mapper.getDeptById(40); //sqlSession.clearCache();清一級快取 //增刪改操作之後也不會有快取 Dept dept2 = mapper.getDeptById(40); //Dept dept2 = mapper.getDeptByIdAndLoc(40, "BOSTON"); System.out.println(dept1 == dept2); //二級快取 /*
sqlSession2 = factory.openSession(); DeptMapper mapper2 = sqlSession2.getMapper(DeptMapper.class); Dept dept2 = mapper2.getDeptById(40); System.out.println(dept1 == dept2); */ } // ...
注意 dept1 == dept2,如果資料庫沒有值得到的結果是 null,那兩個判斷是 true
※一級快取:
1.指同一個 SqlSession 做查詢的快取2.只有 where 條件一樣時,才有快取(如上的例子,就算回傳結果一樣,還是沒快取)
兩個查詢之間有增刪改和呼叫 SqlSession 的 clearCache 方法,都不會有快取
※二級快取:
1..指不同 SqlSession 做查詢的快取2.使用 <cache /> 設定二級快取,其中的屬性可看官網的介紹,其中 readOnly 預設是 false,如果是 false,resultType 的 java bean 必需 implements Serializable,否則會報 java.io.NotSerializableException 的錯,而反序列化後,SQL 就是兩條了,就沒有快取了
3.二個查詢之間必須要將第一個快取 close()後,才會將一級快取裡的值移到二級快取,所以不關閉就不會成功
select 標籤有 useCache,當全域的二級快取是開時,可以針對不想二級快取的 select 關閉
4.<cache-ref> 使用在用另外一支 xml 的 cache
※一、二級快取
在 select 標籤中,還有個 flushCache 可以針對一、二級快取做清除的動作如果一級快取是 STATEMENT;二級快取是 true,一級快取 close()後會將資料移到二級快取,但一級快取之間還是無法共享
sqlSession = factory.openSession(); DeptMapper mapper = sqlSession.getMapper(DeptMapper.class); //一級快取(SqlSession快取) Dept dept1 = mapper.getDeptById(40); Dept dept2 = mapper.getDeptById(40); System.out.println(dept1 == dept2); // false sqlSession.close(); sqlSession2 = factory.openSession(); DeptMapper mapper2 = sqlSession2.getMapper(DeptMapper.class); Dept dept3 = mapper2.getDeptById(40); //System.out.println(dept1 == dept3); System.out.println(dept1 == dept3); // false System.out.println(dept2 == dept3); // true
※如果注解 dept2,那 dept1 == dept3 會是 true,因為 STATEMENT 代表當前的語句
※整合 Ehcache2.x
官方文檔,要下載 ehcache2 和 mybatis 和 ehcache 的 jar 檔, 在根目錄要有 ehcache.xml,可去 ehcache 官網下載,至於設定的意思,可以看到 This file can also be downloaded from 後面有個超連結,會有解釋的;或者 2.x 的 PDF 裡都有要使用時,只要在二級快取的標籤有個 type,指定為 ehcache 就可以了
<cache readOnly="true" type="org.mybatis.caches.ehcache.EhcacheCache" />
※因為使用 <cache> 標籤,所以還是二級快取,一切的行為都和二級快取一樣,但 ehcache.xml 有一個 <diskStore path="aaa.bbb">,這裡面打的 aaa.bbb 並不是 aaa 目錄下有 bbb 目錄,而是 aaa.bbb 的目錄,會出現在 src 下,也可改成磁碟的路徑,這個檔案就算將二級快取關閉,還是會出現,但是行為還是二級快取的行為
※P.S. 我在整合 Ehcache 3.x 的時候,我試了最低的版本和目前最高的版本,XML 都有問題,都會報 Element <ehcache:config> does not allow attribute "xmlns:ehcache" 或 Element <config> does not allow attribute "xmlns:xsi"
沒有留言:
張貼留言