1.緩存
- 查詢數據時將查詢結果存放到內存(緩存區)中。
- 每次查詢數據時,先判斷緩存區中是否存在數據,
- 如果存在,就從緩存區中獲取數據
- 如果不存在,就從數據庫中獲取數據,將數據存放到緩存區中,給下次訪問使用
- 好處:
- 避免頻繁與數據庫交互,提高數據訪問效率。提升系統性能。
- 緩存的使用演示:
- 失敗的一級緩存測試 ※面試相關
[1]SQL語句或查詢條件不同
[2]分屬不同SqlSession對象
[3]查詢前執行clearCache()
[4]提交事務
2.一級緩存
- 一級緩存是SqlSession自帶的。SqlSession對象被創建,一級緩存就存在了。
- 如果SqlSession對象關閉或調用清理方法,會導致緩存失效。
- 緩存底層實現就是通過HashMap實現的。
- 一級緩存介質——內存
3.二級緩存
- 二級緩存介質——內存,硬盤
- 二級緩存SqlSessionFactory進行管理的。SqlSessionFactory對象是進程級別的。可以被多個SqlSession所共享。
跟Web應用中application對象作用範圍類似。
- MyBatis框架自帶了二級緩存,是通過HashMap實現的。
- 二級緩存使用,需要在主文件中進行配置:
- ①啓用二級緩存
- 二級緩存使用,需要在主文件中進行配置:
<!-- 啓用二級緩存 --> <setting name="cacheEnabled" value="true"/> |
- ②在XxxMapper.xml文件中配置二級緩存策略
<cache eviction="FIFO" flushInterval="60000"readOnly="true" size="512"/>
- eviction:緩存策略
- FIFO:First In First Out
- LRU:Least Recently Used
- flushInterval:緩存刷新時間間隔,時間是毫秒,檢查是否存在過期對象
- size:緩存中存儲的對象個數
- readOnly:是否只讀
- ③對於MyBatis自帶的二級緩存,實體類可以不用實現可序列化接口。
- 如果使用的是EhCahce緩存組件,有時會將數據緩存到硬盤上,需要可序列化支持的。必須實現java.io.Serializable
4.外置二級緩存組件
- ehcache緩存組件。
- 實體類必須實現可序列化接口,否則,拋異常。
- java.io.NotSerializableException: com.atguigu.mybatis.bean.Customer
EnhancerByCGLIBEnhancerByCGLIB
eb28a8d2
- java.io.NotSerializableException: com.atguigu.mybatis.bean.Customer
①爲什麼要整合EHCache?
- EHCache更專業,支持內存和硬盤緩存數據。
②操作
[1]添加jar包
- ehcache-core-2.6.8.jar
- mybatis-ehcache-1.0.3.jar
- slf4j-api-1.6.1.jar
[2]加入EHCache自身配置文件ehcache.xml
<ehcache> <!--設置硬盤緩存目錄:內存中存儲不下就可以往這個目錄下存儲了。會自動生成數據文件--> <diskStore path="D:/temp"/> <defaultCache<!--默認的緩存配置--> maxElementsInMemory="10000" maxElementsOnDisk="10000000" eternal="false" timeToIdleSeconds="20" timeToLiveSeconds="120" overflowToDisk="true" diskExpiryThreadIntervalSeconds="120" memoryStoreEvictionPolicy="LRU" /> </ehcache> |
屬性說明: * diskStore:指定數據在磁盤中的存儲位置。 * defaultCache:當藉助CacheManager.add("demoCache")創建Cache時,EhCache便會採用<defalutCache/>指定的的管理策略
以下屬性是必須的: * maxElementsInMemory - 在內存中緩存的element的最大數目 * maxElementsOnDisk - 在磁盤上緩存的element的最大數目,若是0表示無窮大 * eternal - 設定緩存的elements是否永遠不過期。如果爲true,則緩存的數據始終有效,如果爲false那麼還要根據timeToIdleSeconds,timeToLiveSeconds判斷 * overflowToDisk - 設定當內存緩存溢出的時候是否將過期的element緩存到磁盤上
以下屬性是可選的: * timeToIdleSeconds - 當緩存在EhCache中的數據前後兩次訪問的時間超過timeToIdleSeconds的屬性取值時,這些數據便會刪除,默認值是0,也就是可閒置時間無窮大 * timeToLiveSeconds - 緩存element的有效生命期,默認是0.,也就是element存活時間無窮大 diskSpoolBufferSizeMB 這個參數設置DiskStore(磁盤緩存)的緩存區大小.默認是30MB.每個Cache都應該有自己的一個緩衝區. * diskPersistent - 在VM重啓的時候是否啓用磁盤保存EhCache中的數據,默認是false。 * diskExpiryThreadIntervalSeconds - 磁盤緩存的清理線程運行間隔,默認是120秒。每隔120s,相應的線程會進行一次EhCache中數據的清理工作 * memoryStoreEvictionPolicy - 當內存緩存達到最大,有新的element加入的時候, 移除緩存中element的策略。默認是LRU(最近最少使用),可選的有LFU(最不常使用)和FIFO(先進先出) |
[3]開啓EHCache緩存XxxMapper.xml文件中配置
- EhcacheCache實現了Cache接口。
- <cache type="org.mybatis.caches.ehcache.EhcacheCache"/>
[4]測試
openSession = sqlSessionFactory.openSession(); CustomerMapper mapper = openSession.getMapper(CustomerMapper.class);
System.out.println(customer.getCustName()); customer = mapper.getCustomerByCustId(2); System.out.println(customer.getCustName());
openSession.close();
openSession = sqlSessionFactory.openSession(); mapper = openSession.getMapper(CustomerMapper.class);
customer = mapper.getCustomerByCustId(1); System.out.println(customer.getCustName()); |
5.二級緩存的原理:
- Mybatis框架提供了Cache接口,緩存組件實現接口。
- PerpetualCache : 框架默認二級緩存實現類。使用HashMap實現二級緩存的。
6.二級緩存失效情況
[1]在查詢select標籤內設置useCache="false"
<selectid="getStuById" parameterType="Integer"resultType="Student" useCache="false">
selectstu_id stuId,stu_name stuName from tbl_student where stu_id=#{stuId}
</select>
[2]在執行增刪改操作時刷新緩存
<updateid="updateStu"parameterType="com.atguigu.mybatis.entity.Student" flushCache="true">
updatetbl_student set stu_name=#{stuName} where stu_id=#{stuId}
</update>
這是默認設置,通常不必修改
7.緩存命中率
- 從緩存中查找數據的機率
AAA [DEBUG] 2017-04-08 10:57:04,342(1036) --> [main] org.apache.ibatis.cache.decorators.LoggingCache.getObject(LoggingCache.java:62): Cache Hit Ratio [com.atguigu.mybatis.mapper.CustomerMapper]: 0.5 AAA [DEBUG] 2017-04-08 10:57:04,342(1036) --> [main] org.apache.ibatis.cache.decorators.LoggingCache.getObject(LoggingCache.java:62): Cache Hit Ratio [com.atguigu.mybatis.mapper.CustomerMapper]: 0.6 AAA [DEBUG] 2017-04-08 10:57:04,343(1037) --> [main] org.apache.ibatis.cache.decorators.LoggingCache.getObject(LoggingCache.java:62): Cache Hit Ratio [com.atguigu.mybatis.mapper.CustomerMapper]: 0.6666666666666666 AAA [DEBUG] 2017-04-08 10:57:04,343(1037) --> [main] org.apache.ibatis.cache.decorators.LoggingCache.getObject(LoggingCache.java:62): Cache Hit Ratio [com.atguigu.mybatis.mapper.CustomerMapper]: 0.7142857142857143 AAA [DEBUG] 2017-04-08 10:57:04,343(1037) --> [main] org.apache.ibatis.cache.decorators.LoggingCache.getObject(LoggingCache.java:62): Cache Hit Ratio [com.atguigu.mybatis.mapper.CustomerMapper]: 0.75 |
8.數據查找過程:
- 二級緩存 -> 一級緩存 -> 數據庫