日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Mybatis的缓存机制Cache

發布時間:2023/12/18 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Mybatis的缓存机制Cache 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Mybatis提供對緩存的支持,分為一級緩存和二級緩存,在沒有配置的情況下,系統默認會使用一級緩存。

一級緩存(SqlSession級別)

  我們都知道每個SqlSession對象之間的緩存是互不影響的,當同一個SqlSession執行多次相同的SQL語句時(主要針對select),系統只會到底層訪問數據庫一次,后續執行sql時,會從一級緩存里面讀取第一次訪問的數據。當這個SqlSession對象執行close(),或者顯示聲明清空緩存時,對應的一級緩存也會清空,從而提高效率。值得注意的是,如果SqlSession執行DML操作(即insert、update、delete),并提交到數據庫時,也會起到清空該SqlSession對象對應的一級緩存的作用,目的是為了保證緩存里面的數據是最新的。,避免臟讀現象。

二級緩存(SqlSessionFactory級別)

  有些書籍說二級緩存是Mapper級別,可能是依據二級緩存的配置是在xxxMapper.xml上配置的吧,不過本人更認同是SqlSessionFactory級別,為什么呢?因為同一個Configuration里面是創建一個SqlSessionFactory,SqlSessionFactory是屬于線程安全的,SqlSessionFactory可以創建很多個SqlSession來進行事務操作,也就是說,SqlSessionFactory是由很多個SqlSession對象共享的,同樣的,二級緩存的數據也是由很多個SqlSession共享的。如何才能讓系統操作二級緩存呢?原理很簡單,不同的SqlSession對象執行相同的namespace下的sql語句,當第一個SqlSession對象調用close()關閉一級緩存時,第一次查詢得到的數據將會被保存到二級緩存,后面的SqlSession對象調用相同sql語句時,就會從二級緩存中獲取數據。當然,使用二級緩存,需要對應的返回對象(即POJO)實現序列化。

配置:在需要使用的xxxMapper.xml里面配置<cache eviction="LRU" flushInterval="100000" size="1024" readOnly="true" />

eviction:代表回收策略,目前支持4種策略

1.LRU,最近最少使用的,移除最長時間不用的對象;

2.FIFO,先進先出;

3.SOFT,移除基于垃圾回收器狀態和軟引用規則的對象;

4.WEAK,更積極移除基于垃圾回收器狀態和弱引用規則的對象。

flushInterval:代表刷新時長,單位毫秒

size:代表緩存最多可以存儲多少個對象,注意,設置過大會導致內存溢出

readOnly:意味著緩存數據只能讀取,不能修改

上面是較為詳細配置,當然也可以簡單一點,直接寫上<cache />就可以了。

下面給出一個較為有意思的栗子:

xml配置代碼如下:

<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.learn.mapper.EmployeeMapper"><cache /><select id="getEmpList" resultType="employee">select * from tb_employee</select></mapper>

JUnit4測試代碼如下:

@Testpublic void testCache(){SqlSession ss1 = null;SqlSession ss2 = null;try{ss1 = SqlSessionFactoryUtil.initSqlSessionFactory().openSession();ss2 = SqlSessionFactoryUtil.initSqlSessionFactory().openSession();EmployeeMapper em1 = ss1.getMapper(EmployeeMapper.class);EmployeeMapper em2 = ss2.getMapper(EmployeeMapper.class);List<Employee> list1 = em1.getEmpList();//ss1.close();list1 = em2.getEmpList();}catch(Exception e){ss1.rollback();ss2.rollback();e.printStackTrace();}finally{if(ss1 != null){ss1.close();}if(ss2 != null){ss2.close();}}}

代碼中實例化兩個SqlSession對象,分別是ss1和ss2,用戶檢驗數據讀取的操作。留意上面注釋了ss1.close();這一行。

下面是執行上面測試代碼的日志結果:

Logging initialized using 'class org.apache.ibatis.logging.slf4j.Slf4jImpl' adapter. PooledDataSource forcefully closed/removed all connections. PooledDataSource forcefully closed/removed all connections. PooledDataSource forcefully closed/removed all connections. PooledDataSource forcefully closed/removed all connections. Cache Hit Ratio [com.learn.mapper.EmployeeMapper]: 0.0 Opening JDBC Connection Created connection 275310919. Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@1068e947] ==> Preparing: select * from tb_employee ==> Parameters: <== Total: 6 Cache Hit Ratio [com.learn.mapper.EmployeeMapper]: 0.0 Opening JDBC Connection Created connection 1948863195. Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@74294adb] ==> Preparing: select * from tb_employee ==> Parameters: <== Total: 6 Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@1068e947] Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@1068e947] Returned connection 275310919 to pool. Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@74294adb] Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@74294adb] Returned connection 1948863195 to pool.

可以看到即使配置了<cache />二級緩存,第一個SqlSession對象ss1沒有手動執行close()方法時,ss1對應的一級緩存數據仍然沒有保存到二級緩存里面,即二級緩存里面沒有數據,當第二個SqlSession對象ss2執行相同的sql語句時,會找一級緩存有沒有數據,因為第一次執行,當然沒有數據了,然后找二級緩存,剛才說過了,ss1的一級緩存數據并沒有保存到二級緩存里面,所以二級緩存也沒有數據,因此ss2就會再次操作數據庫。可以看到log日志會有兩條select語句。

此時,如果將close();的注釋去掉,再執行一下測試代碼,日志結果如下:

Logging initialized using 'class org.apache.ibatis.logging.slf4j.Slf4jImpl' adapter. PooledDataSource forcefully closed/removed all connections. PooledDataSource forcefully closed/removed all connections. PooledDataSource forcefully closed/removed all connections. PooledDataSource forcefully closed/removed all connections. Cache Hit Ratio [com.learn.mapper.EmployeeMapper]: 0.0 Opening JDBC Connection Created connection 275310919. Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@1068e947] ==> Preparing: select * from tb_employee ==> Parameters: <== Total: 6 Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@1068e947] Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@1068e947] Returned connection 275310919 to pool. Cache Hit Ratio [com.learn.mapper.EmployeeMapper]: 0.5

顯而易見,此時只訪問一次數據庫。

轉載于:https://www.cnblogs.com/SysoCjs/p/9574318.html

總結

以上是生活随笔為你收集整理的Mybatis的缓存机制Cache的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。