MyBatis的緩存玩法

重要概念

  • SqlSession:代表和數據庫的一次會話,提供了操作數據庫的方法。

  • MappedStatement:代表要發往數據執行的命令,可以理解為SQL的抽象表示。

  • Executor:和數據庫交互的執行器,接收MappedStatement。

  • 映射接口:在接口中會要執行的SQL用一個方法表示,具體SQL寫在映射文件中。

  • 映射文件:編寫SQL的文件。

一級緩存介紹

在代碼運行時,有可能會在一個數據庫會話中執行多次相同的SQL,這種反覆的查詢會帶來開銷。

每一個SqlSession都持有自己的緩存,就是LocalCache。一種是Session級別的,在Mybatis中執行的所有語句都會共享這一個緩存。一種是Statement級別的,緩存只對當前statement語句。

當發起查詢時,Mybatis會根據statementId、params、rowBounds生成一個key,去Cache查,如果沒有的話會去數據庫查,並且緩存到本地。

image

一級緩存的不足

使用一級緩存的時候,因為緩存不能跨會話共享,不同的會話之間對於相同的數據可能有不一樣的緩存。在有多個會話或者分佈式環境下,會存在臟數據的問題。如果要解決這個問題,就要用到二級緩存。MyBatis 一級緩存無法關閉,但是有兩種級別可選:

  1. session級別的緩存,在同一個sqlSession內,對同樣的查詢將不再查詢數據庫,直接從緩存中取。

  2. statement級別的緩存,為了避免上述問題,可以將一級緩存的級別設為 statement 級別的,這樣每次查詢結束都會清掉一級緩存。

二級緩存

二級緩存是用來解決一級緩存不能跨會話共享的問題的,在XML文件配置後可以被多個SqlSession共享,生命周期和應用同步。

如果MyBatis使用了二級緩存,並且Mapper和select語句也配置使用了二級緩存,那麼在執行select查詢的時候,MyBatis會先從二級緩存中取輸入,其次才是一級緩存。

即MyBatis查詢數據的順序是:二級緩存 —> 一級緩存 —> 數據庫。

//www.cnblogs.com/wuzhenzhao/p/11103043.html

image

一、二級緩存的使用注意點

  • MyBatis默認的session級別一級緩存,由於Spring Boat 中默認使用了hikariCP,所以基本沒用,需要開啟事務才有用。但一級緩存作用域僅限同一sqlSession內,無法感知到其他sqlSession的增刪改,所以極易產生臟數據。

  • 二級緩存可通過cache-ref讓多個mapper.xml共享同一namespace,從而實現緩存共享,但多表聯查時配置略微繁瑣。

  • 生產環境建議將一級緩存設置為statment級別(即關閉一級緩存),如果有必要,可以開啟二級緩存。

  • 在分佈式環境中也是不建議開啟二級緩存的,因為緩存是保存到本地的,這樣也會導致產生臟數據。