mybatis--緩存(一級和二級緩存)

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

①爲什麼要整合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);


Customer customer = mapper.getCustomerByCustId(1);

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.數據查找過程:

  • 二級緩存 -> 一級緩存 -> 數據庫
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章