MyBatis的緩存玩法
重要概念
-
SqlSession:代表和數據庫的一次會話,提供了操作數據庫的方法。
-
MappedStatement:代表要發往數據執行的命令,可以理解為SQL的抽象表示。
-
Executor:和數據庫交互的執行器,接收MappedStatement。
-
映射接口:在接口中會要執行的SQL用一個方法表示,具體SQL寫在映射文件中。
-
映射文件:編寫SQL的文件。
一級緩存介紹
在代碼運行時,有可能會在一個數據庫會話中執行多次相同的SQL,這種反覆的查詢會帶來開銷。
每一個SqlSession都持有自己的緩存,就是LocalCache。一種是Session級別的,在Mybatis中執行的所有語句都會共享這一個緩存。一種是Statement級別的,緩存只對當前statement語句。
當發起查詢時,Mybatis會根據statementId、params、rowBounds生成一個key,去Cache查,如果沒有的話會去數據庫查,並且緩存到本地。
一級緩存的不足
使用一級緩存的時候,因為緩存不能跨會話共享,不同的會話之間對於相同的數據可能有不一樣的緩存。在有多個會話或者分佈式環境下,會存在臟數據的問題。如果要解決這個問題,就要用到二級緩存。MyBatis 一級緩存無法關閉,但是有兩種級別可選:
-
session級別的緩存,在同一個sqlSession內,對同樣的查詢將不再查詢數據庫,直接從緩存中取。
-
statement級別的緩存,為了避免上述問題,可以將一級緩存的級別設為 statement 級別的,這樣每次查詢結束都會清掉一級緩存。
二級緩存
二級緩存是用來解決一級緩存不能跨會話共享的問題的,在XML文件配置後可以被多個SqlSession共享,生命周期和應用同步。
如果MyBatis使用了二級緩存,並且Mapper和select語句也配置使用了二級緩存,那麼在執行select查詢的時候,MyBatis會先從二級緩存中取輸入,其次才是一級緩存。
即MyBatis查詢數據的順序是:二級緩存 —> 一級緩存 —> 數據庫。
一、二級緩存的使用注意點
-
MyBatis默認的session級別一級緩存,由於Spring Boat 中默認使用了hikariCP,所以基本沒用,需要開啟事務才有用。但一級緩存作用域僅限同一sqlSession內,無法感知到其他sqlSession的增刪改,所以極易產生臟數據。
-
二級緩存可通過cache-ref讓多個mapper.xml共享同一namespace,從而實現緩存共享,但多表聯查時配置略微繁瑣。
-
生產環境建議將一級緩存設置為statment級別(即關閉一級緩存),如果有必要,可以開啟二級緩存。
-
在分佈式環境中也是不建議開啟二級緩存的,因為緩存是保存到本地的,這樣也會導致產生臟數據。