「每日分享」Hibernate和Mybaitis緩存對比

點擊上方"java全棧技術"關注,每天學習一個java知識點,喜歡的也可以關注微信公眾號"ITeye"

「每日分享」Hibernate和Mybaitis緩存對比

前言

本篇意在通過Hibernate和Mybaitis緩存,通過對比學習,同時弄懂這兩者中的區別

Hibernate中的緩存

Hibernate中一般常用的緩存有三個,一級緩存,二級緩存,查詢緩存,要了解一二級緩存的可以查看之前的文章,這裡主要講解一下二級緩存和查詢緩存。

首先我們先看一下Hibernate的二級緩存

「每日分享」Hibernate和Mybaitis緩存對比

文字描述過程:

  • 首先我們get(1L)的時候,由於二級緩存中沒有,所以我們就去數據庫查詢,並將結果返回後插入到二級緩存中,然後將結果插入到二級緩存中,並將數據返回.
  • 當我們再次查詢時,由於二級緩存中已經存在了該對象,那麼我們就不用到數據庫中查詢,直接從緩存中把結果返回

那麼我們再來看看Hibernate中的查詢緩存

「每日分享」Hibernate和Mybaitis緩存對比

文字描述過程:

  • 首先list()的時候,由於查詢緩存中沒有,那麼我們去數據庫查,並將數據放在了查詢緩存中,然後將結果返回
  • 當我們進行insert操作的時候,首先會給數據庫增加一條數據,然後關鍵的地方來了,此時Hibernate會清空所有的查詢緩存,因為此時數據庫中的數據已經變了,如果不清空緩存,就會導致select * from User拿到的還是1L和2L,但是此時正確的應該是1L,2L,3L,所以必須清空
  • 然後我們再次list()的時候,又重複第一步的操作

從以上過程我們就可以看出,Hibernate的查詢緩存的命中率的非常低的,進行新增、編輯、刪除操作都會去清空查詢緩存,所以一般不使用查詢緩存,而是使用二級緩存.

Mybaitis中的緩存

一般我們都不說MyBatis的二級緩存,而是說MyBatis的緩存,我們先來看代碼

「每日分享」Hibernate和Mybaitis緩存對比

這段代碼中, Mybatis一共發了兩條SQL,這就好像說, Mybatis中沒有二級緩存,然後我們打開Mybatis的文檔一看,頓時震驚

「每日分享」Hibernate和Mybaitis緩存對比

這難道是騙人的,說好的默認開啟緩存呢.....

其實不是的,默認確實是開啟緩存的,但是我們還需要配置一點東西

UserMapper.xml

「每日分享」Hibernate和Mybaitis緩存對比

另外,對象還要實現序列化接口,否則報NotSerializableException的異常

「每日分享」Hibernate和Mybaitis緩存對比

設置完畢之後,我們再來嘗試insert的問題

「每日分享」Hibernate和Mybaitis緩存對比

此時發現,發了3條SQL,那麼究竟是什麼原因呢?

首先,get的底層用的是selectOne,然後selectOne又用的是用selectList,所以Mybatis是沒有二級緩存的概念,他的緩存,全都是查詢緩存.此時如下圖

「每日分享」Hibernate和Mybaitis緩存對比

看完這個圖,就明白為什麼get(1L)->add()->get(1L)這個過程會發3條SQL了,因為insert的時候,清空了緩存

但是就算insert,並沒有影響到get(1L)的結果,但是你卻把他的緩存也清空了,這明顯不合理,那麼我們怎麼樣讓Mybatis中的緩存更像Hibernate中的二級緩存呢?因為目前這樣的緩存實在太坑,從這過程大家應該感受得到.

那麼我們可不可以這樣做呢?如圖:

「每日分享」Hibernate和Mybaitis緩存對比

mybatis緩存改進.png

也就是我們做了兩件事

  • list由於緩存命中率低,那麼我們就不加入到緩存中
  • insert我們不清空緩存

這樣做,Mybatis的緩存就顯得更像Hibernate中的二級緩存了,那麼在代碼中,我們具體是怎麼實現的呢?

UserMapper.xml

「每日分享」Hibernate和Mybaitis緩存對比

這樣之後,我們Mybatis中的緩存就更高效了

鏈接:https://www.jianshu.com/p/fe4d82c8c97c


分享到:


相關文章: