MyBatis緩存通俗易懂


1.1     mybatis緩存介紹

如下圖,是mybatis一級緩存和二級緩存的區別圖解:

 

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

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

 

 

1.2     一級緩存

1.2.1  原理

下圖是根據id查詢用戶的一級緩存圖解:

 

一級緩存區域是根據SqlSession為單位划分的。

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

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

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

 

1.2.2  測試1

//獲取session

       SqlSession session = sqlSessionFactory.openSession();

       //獲限mapper接口實例

       UserMapper userMapper = session.getMapper(UserMapper.class);

       //第一次查詢

       User user1 = userMapper.findUserById(1);

       System.out.println(user1);

//第二次查詢,由於是同一個session則不再向數據發出語句直接從緩存取出

       User user2 = userMapper.findUserById(1);

       System.out.println(user2);

//關閉session

       session.close();

 

1.2.3  測試2

 

//獲取session

       SqlSession session = sqlSessionFactory.openSession();

       //獲限mapper接口實例

       UserMapper userMapper = session.getMapper(UserMapper.class);

       //第一次查詢

       User user1 = userMapper.findUserById(1);

       System.out.println(user1);

       //在同一個session執行更新

       User user_update = new User();

       user_update.setId(1);

       user_update.setUsername("李奎");

       userMapper.updateUser(user_update);

       session.commit();

       //第二次查詢,雖然是同一個session但是由於執行了更新操作session的緩存被清空,這里重新發出sql操作

       User user2 = userMapper.findUserById(1);

       System.out.println(user2);

 

 

1.3     二級緩存

1.3.1  原理

下圖是多個sqlSession請求UserMapper的二級緩存圖解。

 

 

二級緩存區域是根據mapper的namespace划分的,相同namespace的mapper查詢數據放在同一個區域,如果使用mapper代理方法每個mapper的namespace都不同,此時可以理解為二級緩存區域是根據mapper划分。

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

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

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

 

 

1.3.2  開啟二級緩存:

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

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

 

 

描述

允許值

默認值

cacheEnabled

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

true false

true

 

 

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

 

1.3.3  實現序列化

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

         public class Orders implements Serializable

         public class User implements Serializable

         ....

 

1.3.4  測試

 

//獲取session1

       SqlSession session1 = sqlSessionFactory.openSession();

       UserMapper userMapper = session1.getMapper(UserMapper.class);

       //使用session1執行第一次查詢

       User user1 = userMapper.findUserById(1);

       System.out.println(user1);

       //關閉session1

       session1.close();

       //獲取session2

       SqlSession session2 = sqlSessionFactory.openSession();

       UserMapper userMapper2 = session2.getMapper(UserMapper.class);

       //使用session2執行第二次查詢,由於開啟了二級緩存這里從緩存中獲取數據不再向數據庫發出sql

       User user2 = userMapper2.findUserById(1);

       System.out.println(user2);

       //關閉session2

       session2.close();

 

 

1.3.5  禁用二級緩存

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

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

 

1.3.6  刷新緩存

在mapper的同一個namespace中,如果有其它insert、update、delete操作數據后需要刷新緩存,如果不執行刷新緩存會出現臟讀。

 

 設置statement配置中的flushCache="true" 屬性,默認情況下為true即刷新緩存,如果改成false則不會刷新。使用緩存時如果手動修改數據庫表中的查詢數據會出現臟讀。

如下:

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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM