(1).爲何須要使用緩存::java
MyBatis是一個持久層(數據庫層)映射框架,在全部訪問數據庫的操做中,無疑數據查詢是最耗費數據庫資源的操做了,由於你一次可能須要查詢成千上百萬條記錄(若是你不加限制),因此當你對數據庫的實時性要求不高的狀況下,能夠將第一次執行查詢的操做的結果存放在本地緩存中,當你在短期內執行相同查詢時,就能夠直接從本地緩存加載而不用去數據庫查詢,即提升了速度,又下降了數據庫的壓力。sql
(2)以下圖,是mybatis一級緩存和二級緩存的區別圖解:數據庫
Mybatis一級緩存的做用域是同一個SqlSession,在同一個sqlSession中兩次執行相同的sql語句,第一次執行完畢會將數據庫中查詢的數據寫到緩存(內存),第二次會從緩存中獲取數據將再也不從數據庫查詢,從而提升查詢效率。當一個sqlSession結束後該sqlSession中的一級緩存也就不存在了。Mybatis默認開啓一級緩存。緩存
Mybatis二級緩存是多個SqlSession共享的,其做用域是mapper的同一個namespace,不一樣的sqlSession兩次執行相同namespace下的sql語句且向sql中傳遞參數也相同即最終執行相同的sql語句,第一次執行完畢會將數據庫中查詢的數據寫到緩存(內存),第二次會從緩存中獲取數據將再也不從數據庫查詢,從而提升查詢效率。Mybatis默認沒有開啓二級緩存須要在setting全局參數中配置開啓二級緩存。session
Mybatis每次查詢會先從緩存區域找,若是找不到從數據庫查詢,查詢到數據將數據寫入緩存。mybatis
Mybatis內部存儲緩存使用一個HashMap,key爲hashCode+sqlId+Sql語句。value爲從查詢出來映射生成的java對象,sqlSession執行insert、update、delete等操做commit提交後會清空緩存區域。app
(3)如何使用MyBatis緩存框架
第一步:引進緩存的依賴包spa
第二步:引進緩存配置文件線程
classpath下添加:ehcache.xml(src文件的同級文件,即原放置MyBatis-config.xml同個位置)
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../config/ehcache.xsd"> <diskStore path="F:\develop\ehcache" /> <defaultCache maxElementsInMemory="1000" maxElementsOnDisk="10000000" eternal="false" overflowToDisk="false" timeToIdleSeconds="120" timeToLiveSeconds="120" diskExpiryThreadIntervalSeconds="120" memoryStoreEvictionPolicy="LRU"> </defaultCache> </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(先進先出)
第三步:開啓ehcache緩存
EhcacheCache是ehcache對Cache接口的實現:
修改mapper.xml文件,在cache中指定EhcacheCache。<mapper>標籤內
<cache />
或(開啓ehcache緩存)
<cache type="org.mybatis.caches.ehcache.EhcacheCache"/>
或(根據須要調節緩存參數)
<cache type="org.mybatis.caches.ehcache.EhcacheCache" > <property name="timeToIdleSeconds" value="3600"/> <property name="timeToLiveSeconds" value="3600"/> <!-- 同ehcache參數maxElementsInMemory --> <property name="maxEntriesLocalHeap" value="1000"/> <!-- 同ehcache參數maxElementsOnDisk --> <property name="maxEntriesLocalDisk" value="10000000"/> <property name="memoryStoreEvictionPolicy" value="LRU"/> </cache>
這樣設置就配置好MyBatis的緩存環境了。
當你短期內使用同一個session 執行一樣的SQL語句,而且條件也相同時,它就會去緩存內提取數據了
(4)如何使用二級緩存
前面說過了二級緩存是對應整個Mapper的,但它默認是關閉的,那咱們怎麼使用它呢?
第一步:在覈心配置文件mybatis-config.xml中加入
<setting name="cacheEnabled" value="true"/>
在你的Mapper映射文件中添加一行: <cache /> ,表示此mapper開啓二級緩存。
(5)實現序列化
二級緩存須要查詢結果映射的pojo對象實現java.io.Serializable接口實現序列化和反序列化操做,注意若是存在父類、成員pojo都須要實現序列化接口。
(即實體類繼承以下接口)
public class Order implements Serializable public class User implements Serializable
(6)禁用二級緩存
在statement中設置useCache=false能夠禁用當前select語句的二級緩存,即每次查詢都會發出sql去查詢,默認狀況是true,即該sql使用二級緩存。
若是某條SQL語句實時性要求不想讓其使用緩存,只需在其sql標籤內添加usecache="false"便可;以下所示
<select id="findOrderListResultMap" resultMap="ordersUserMap" useCache="false">
(7)禁用刷新緩存
在mapper的同一個namespace中,若是有其它insert、update、delete操做數據後須要刷新緩存,若是不執行刷新緩存會出現髒讀。
設置statement配置中的flushCache="true" 屬性,默認狀況下爲true即刷新緩存,若是改爲false則不會刷新。使用緩存時若是手動修改數據庫表中的查詢數據會出現髒讀。
以下:
<insert id="insertUser" parameterType="cn.itcast.mybatis.po.User" flushCache="true">