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

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

缓存在哪里_什么是MyBatis缓存技术

發(fā)布時(shí)間:2023/12/4 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 缓存在哪里_什么是MyBatis缓存技术 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

MyBatis緩存

引言

在一個(gè)Web項(xiàng)目中,查詢數(shù)據(jù)庫(kù)中的操作算是一個(gè)非常常用的操作,但是有些數(shù)據(jù)會(huì)被經(jīng)常性的查詢,而每一次都去數(shù)據(jù)庫(kù)中查詢這些重復(fù)的數(shù)據(jù),會(huì)很消耗數(shù)據(jù)庫(kù)的資源,同時(shí)使得查詢效率也很低,而 MyBatis 中就通過(guò)緩存技術(shù)來(lái)解決這樣的問(wèn)題,也就是說(shuō):將一些經(jīng)常查詢,并且不經(jīng)常改變的,以及數(shù)據(jù)的正確對(duì)最后的結(jié)果影響不大的數(shù)據(jù),放置在一個(gè)緩存容器中,當(dāng)用戶再次查詢這些數(shù)據(jù)的時(shí)候,就不必再去數(shù)據(jù)庫(kù)中查詢,直接在緩存中提取就可以了

注:緩存可以簡(jiǎn)單理解為存在于內(nèi)存中的臨時(shí)數(shù)據(jù)

MyBatis 提供了 一級(jí)緩存和二級(jí)緩存兩種形式

  • 一級(jí)緩存 :它是 SqlSession 級(jí)別的緩存,SqlSession 類的實(shí)例對(duì)象中提供了一個(gè) HashMap 的結(jié)構(gòu),可以用于存儲(chǔ)緩存數(shù)據(jù),當(dāng)我們?cè)俅尾樵兺粩?shù)據(jù)的時(shí)候,MyBatis 會(huì)先去 SqlSession 中查詢,有的話,就直接調(diào)用
  • 二級(jí)緩存 :是Mapper 級(jí)別的緩存,也就是說(shuō),如果多個(gè) SqlSession 類的實(shí)例,去操作同一個(gè)Mapper配置文件中的SQL,這些實(shí)例對(duì)象可以共用二級(jí)緩存

一級(jí)緩存

(1) 基本闡述

上面我們總的講了一級(jí)緩存的原理,現(xiàn)在梳理一下它細(xì)節(jié)

以一個(gè)通過(guò) id 查詢用戶的例子來(lái)說(shuō)

  • 第一次查詢 id 為某個(gè)值的用戶信息時(shí),先去 SqlSesion 的一級(jí)緩存中去尋找,如果找到了,就直接用,如果沒有找到就去數(shù)據(jù)庫(kù)中去查,然后將查到的內(nèi)容存到一級(jí)緩存區(qū)域
  • 但是,如果在下一次操作中,執(zhí)行了 commit 操作,也就是執(zhí)行了增刪改的操作,一級(jí)緩存區(qū)域內(nèi)的內(nèi)容會(huì)被清空,這是為了保證緩存中的數(shù)據(jù)的有效性,避免臟讀的產(chǎn)生

(2) 程序演示

演示前,我把需要準(zhǔn)備的一些類或者表現(xiàn)貼出來(lái)

User表

CREATE TABLE USER ( `id` INT(11)NOT NULL AUTO_INCREMENT, `username` VARCHAR(32) NOT NULL COMMENT '用戶名', `telephone` VARCHAR(11) NOT NULL COMMENT '手機(jī)', `birthday` DATETIME DEFAULT NULL COMMENT '生日', `gender` CHAR(1) DEFAULT NULL COMMENT '性別', `address` VARCHAR(256) DEFAULT NULL COMMENT '地址', PRIMARY KEY (`id`)) ENGINE=INNODB DEFAULT CHARSET=utf8;

User實(shí)體類

public class User implements Serializable { private Integer id; private String username; private String telephone; private Date birthday; private String gender; private String address; ...... 請(qǐng)補(bǔ)充 get set 方法}

UserMapper接口

public interface UserMapper { /** * 根據(jù)id查詢用戶信息 * @param userId * @return */ User findById(Integer userId);}

UserMapper.xml

<?xml version="1.0" encoding="UTF-8"?> SELECT * FROM user where id = #{uid}

測(cè)試方法

/*** 測(cè)試查詢所有*/@Testpublic void testFirstLevelCache() { User user1 = userMapper.findById(16); System.out.println(user1); User user2 = userMapper.findById(16); System.out.println(user2); System.out.println(user1 == user2);}

執(zhí)行效果

可以很明顯的看到,當(dāng)我們?cè)谕粋€(gè) sqlSession的情況下,當(dāng)我們第一次查詢 id 值為 16 的用戶時(shí),從數(shù)據(jù)庫(kù)中確實(shí)查詢到了數(shù)據(jù),而第二次查詢的時(shí)候,卻沒有任何日志的數(shù)據(jù),而同時(shí)我們可以看到,通過(guò)輸出語(yǔ)句,看到兩個(gè)對(duì)象是完全相同的,這也就意味著,第二次查詢不是從數(shù)據(jù)庫(kù)查詢出來(lái)的,而是從緩存中

二級(jí)緩存

(1) 基本闡述

通過(guò)上面的簡(jiǎn)單認(rèn)識(shí),我們認(rèn)識(shí)到一級(jí)緩存是基于同一個(gè) SqlSession的,但是有時(shí)候由于方法封裝的原因,或者在查詢完,SqlSession 對(duì)象會(huì)關(guān)閉,一級(jí)緩存就清空了,會(huì)導(dǎo)致無(wú)法從中獲取內(nèi)容

二級(jí)緩存的可以幫我們解決一級(jí)緩存無(wú)法使用的情況,前面已經(jīng)說(shuō)過(guò)二級(jí)緩存是Mapper 級(jí)別的緩存,多個(gè)SqlSession類的實(shí)例對(duì)象加載同一個(gè)Mapper配置文件,并執(zhí)行其中SQL配置的收,他們就共享同一個(gè) Mapper 緩存,執(zhí)行流程也與一級(jí)緩存基本是一致的

  • 查詢時(shí),先去Mapper緩存區(qū)去找這個(gè)值,如果找不到,就去數(shù)據(jù)庫(kù)查,然后將查詢到的結(jié)果存儲(chǔ)到緩存中,等下次使用
  • 當(dāng)某個(gè) SqlSession 類的實(shí)例對(duì)象執(zhí)行了增刪改操作時(shí),二級(jí)緩存會(huì)被清空

還依據(jù)剛開始準(zhǔn)備的代碼,我們直接寫出其測(cè)試代碼,看看在不同的 SqlSession 下,加載同一個(gè)Mapper的SQL是否會(huì)看到二級(jí)緩存的效果

(2) 程序演示

測(cè)試代碼

@Testpublic void testSecondLevelCache() { SqlSession sqlSession1 = factory.openSession(); UserMapper mapper1 = sqlSession1.getMapper(UserMapper.class); User user1 = mapper1.findById(16); sqlSession1.close(); SqlSession sqlSession2 = factory.openSession(); UserMapper mapper2 = sqlSession2.getMapper(UserMapper.class); User user2 = mapper2.findById(16); sqlSession1.close(); System.out.println(user1 == user2);}

第一次執(zhí)行效果

看完測(cè)試代碼,我們發(fā)現(xiàn),SQL執(zhí)行了兩次,很顯然,沒有達(dá)到了我們的期望,那么是哪里不對(duì)呢?

答案是,在MyBatis中一級(jí)緩存是默認(rèn)開啟的,而二級(jí)緩存則需要進(jìn)行配置開啟

要開啟二級(jí)緩存,需要進(jìn)行兩個(gè)操作步驟

  • ①:在總配置文件 SqlMapConfig.xml 中配置 setting屬性
  • ②:在SQL映射文件中開啟二級(jí)緩存

通過(guò)官網(wǎng)的文檔,可以看到,默認(rèn)值就是true,所以,不配置也是可以的,不過(guò)我們還是先給出來(lái)

修改 SqlMapConfig.xml

修改 UserMapper.xml

只需要在文件中添加一個(gè) cache標(biāo)簽就可以了,非常簡(jiǎn)單

執(zhí)行效果

還有一個(gè)需要注意的地方,那就是我們最后做的判斷 System.out.println(user1 == user2); 為什么的到的結(jié)果卻是 false呢?

這是因?yàn)?#xff0c;在二級(jí)緩存中,存入的是值,而不是對(duì)象,當(dāng)需要使用的時(shí)候,會(huì)創(chuàng)建出新的用戶,然后將值傳入,所以這里是不等的

不過(guò)使用二級(jí)緩存的時(shí)候,一定要謹(jǐn)慎,因?yàn)橛袝r(shí)候不同的namespace下的 SQL配置中可能緩存著相同的數(shù)據(jù),如我們上面的例子,UserMapper.xml 中有關(guān)于 user表的操作,但是如果在其他 Mmpper.xml 中仍然有針對(duì) user 單表的操作,這會(huì)導(dǎo)致兩方數(shù)據(jù)不一樣,如果在我們 UserMapper.xml 進(jìn)行了刷新緩存,但是另一個(gè)Mapper.xml 中可能仍有效,所以可能會(huì)出現(xiàn)錯(cuò)誤

總結(jié)

以上是生活随笔為你收集整理的缓存在哪里_什么是MyBatis缓存技术的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。