Mybatis延遲加載和查詢緩存

1、延遲加載

  resultMap能夠實現高級映射(使用association、collection實現一對一及一對多映射),association、collection具有延遲加載功能。java

  延遲加載:先從單表查詢,須要時再從關聯表去關聯查詢,大大提升數據庫性能,由於查詢單表要比關聯查詢多張錶速度要快。sql

在mybatis核心配置文件中配置:數據庫

lazyLoadingEnabled、aggressiveLazyLoading緩存

設置項數據結構

描述mybatis

容許值app

默認值性能

lazyLoadingEnabledspa

全局性設置懶加載。若是設爲‘false’,則全部相關聯的都會被初始化加載。代理

true | false

false

aggressiveLazyLoading

當設置爲‘true’的時候,懶加載的對象可能被任何懶屬性所有加載。不然,每一個屬性都按需加載。

true | false

true

<settings>

      <setting name="lazyLoadingEnabled" value="true"/>

      <setting name="aggressiveLazyLoading" value="false"/>

</settings>

  場合:

         當只有部分記錄須要關聯查詢其它信息時,此時可按需延遲加載,須要關聯查詢時再向數據庫發出sql,以提升數據庫性能。

         當所有須要關聯查詢信息時,此時不用延遲加載,直接將關聯查詢信息所有返回便可,可以使用resultType或resultMap完成映射。

 

2、查詢緩存

  Mybatis提供查詢緩存,用於減輕數據壓力,提升數據庫壓力。

  Mybatis提供一級緩存和二級緩存。

  

  在操做數據庫時須要構造SqlSession對象,在對象中有一個數據結構(HashMap)用於緩存數據。

  不一樣的SqlSession之間的緩存數據區域是互相不影響的。

  Mybatis一級緩存的做用域是同一個SqlSession,在同一個sqlSession中兩次執行相同的sql語句,第一次執行完畢會將數據庫中查詢的數據寫到緩存(內存),第二次會從緩存中獲取數據將再也不從數據庫查詢,從而提升查詢效率。當一個sqlSession結束後該sqlSession中的一級緩存也就不存在了。Mybatis默認開啓一級緩存。

   Mybatis二級緩存是多個SqlSession共享的,其做用域是mapper的同一個namespace,不一樣的sqlSession兩次執行相同namespace下的sql語句且向sql中傳遞參數也相同即最終執行相同的sql語句,第一次執行完畢會將數據庫中查詢的數據寫到緩存(內存),第二次會從緩存中獲取數據將再也不從數據庫查詢,從而提升查詢效率。Mybatis默認沒有開啓二級緩存須要在setting全局參數中配置開啓二級緩存。

  一、一級緩存

  

  第一次發起查詢,先去找緩存中是否有id爲1的用戶信息,若是沒有,從數據庫中查詢用戶信息。

  獲得用戶信息,將用戶信息存儲到一級緩存中。

  第二次發起查詢用戶id爲1的用戶信息,先去緩存中是否有id爲1的用戶信息,緩存中有,直接從緩存中獲取用戶信息。

  若是SqlSession去執行commit操做(執行插入、更新、刪除),清空SqlSession中的一級緩存。目的是爲了讓緩存中存儲的是最新的信息,避免髒讀。

  Mybatis默認支持一級緩存,不須要在配置文件中配置。

  Mybatis內部存儲緩存使用一個HashMap,key爲hashCode+sqlId+Sql語句。value爲從查詢出來映射生成的java對象。

  應用場景:

  

  二、二級緩存

  

  SqlSession1去查詢用戶id爲1的用戶信息,查詢到用戶信息會將查詢數據存儲到二級緩存中。

  SqlSession2去查詢用戶id爲1的用戶信息,去緩存中找是否存在數據,若是存在直接從緩存中取出數據。

  二級緩存區域是根據mapper的namespace劃分的,相同namespace的mapper查詢數據放在同一個區域,若是使用mapper代理方法每一個mapper的namespace都不一樣,此時能夠理解爲二級緩存區域是根據mapper劃分。

每次查詢會先從緩存區域找,若是找不到從數據庫查詢,查詢到數據將數據寫入緩存。

  Mybatis內部存儲緩存使用一個HashMap,key爲hashCode+sqlId+Sql語句。value爲從查詢出來映射生成的java對象

  sqlSession執行insert、update、delete等操做commit提交後會清空緩存區域。

  開啓二級緩存

  在覈心配置文件SqlMapConfig.xml中加入

<setting name="cacheEnabled" value="true"/>
 

描述

容許值

默認值

cacheEnabled

對在此配置文件下的全部cache 進行全局性開/關設置。

true false

true


要在你的Mapper映射文件中添加一行:  <cache /> ,表示此mapper開啓二級緩存。

  二級緩存須要查詢結果映射的pojo對象實現java.io.Serializable接口實現序列化和反序列化操做,注意若是存在父類、成員pojo都須要實現序列化接口。

  爲了將緩存數據取出執行反序列化,由於二級緩存存儲介質多種多樣,不必定在內存。

  禁用二級緩存:

  在statement中設置useCache=false能夠禁用當前select語句的二級緩存,即每次查詢都會發出sql去查詢,默認狀況是true,即該sql使用二級緩存。

  <select id="findOrderListResultMap" resultMap="ordersUserMap" useCache="false">

  刷新緩存(就是清空緩存)

  設置statement配置中的flushCache="true" 屬性,默認狀況下爲true即刷新緩存,若是改爲false則不會刷新。使用緩存時若是手動修改數據庫表中的查詢數據會出現髒讀。

  <insert id="insertUser" parameterType="cn.itcast.mybatis.po.User" flushCache="true">

  應用場景

  對於訪問多的查詢請求且用戶對查詢結果實時性要求不高,此時可採用mybatis二級緩存技術下降數據庫訪問量,提升訪問速度,業務場景好比:耗時較高的統計分析sql、電話帳單查詢sql等。

      實現方法以下:經過設置刷新間隔時間,由mybatis每隔一段時間自動清空緩存,根據數據變化頻率設置緩存刷新間隔flushInterval,好比設置爲30分鐘、60分鐘、24小時等,根據需求而定。

  侷限性

  mybatis二級緩存對細粒度的數據級別的緩存實現很差,好比以下需求:對商品信息進行緩存,因爲商品信息查詢訪問量大,可是要求用戶每次都能查詢最新的商品信息,此時若是使用mybatis的二級緩存就沒法實現當一個商品變化時只刷新該商品的緩存信息而不刷新其它商品的信息,由於mybaits的二級緩存區域以mapper爲單位劃分,當一個商品信息變化會將全部商品信息的緩存數據所有清空。解決此類問題須要在業務層根據需求對數據有針對性緩存。

相關文章
相關標籤/搜索