国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達(dá)式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務(wù)器之家 - 編程語言 - Java教程 - MyBatis查詢緩存實例詳解

MyBatis查詢緩存實例詳解

2020-11-19 10:24我可能是個假開發(fā) Java教程

查詢緩存的使用,主要是為了提高查詢訪問速度。這篇文章主要介紹了MyBatis查詢緩存,需要的朋友可以參考下

查詢緩存的使用,主要是為了提高查詢訪問速度。將用戶對同一數(shù)據(jù)的重復(fù)查詢過程簡化,不再每次均從數(shù)據(jù)庫查詢獲取結(jié)果數(shù)據(jù),從而提高訪問速度。

mybatis的查詢緩存機制,根據(jù)緩存區(qū)的作用域(生命周期)可劃分為兩種:一級緩存與二級緩存

一、一級查詢緩存

mybatis一級緩存是基于org.apache.ibatis.cache.impl.perpetualcache類的hashmap本地緩存,其作用域是sqlsession。在同一個sqlsession中兩次執(zhí)行相同的sql語句,第一次執(zhí)行完畢后,會將查詢結(jié)果寫入到緩存中,第二次會從緩存中直接獲取數(shù)據(jù),而不再到數(shù)據(jù)庫中進(jìn)行查詢,從而提高查詢效率。

當(dāng)一個sqlsession結(jié)束后,該sqlsession中的一級緩存也就不存在了。mybatis默認(rèn)一級緩存是開啟狀態(tài),且不能關(guān)閉。

MyBatis查詢緩存實例詳解

1.一級緩存的存在性證明

測試類:

?
1
2
3
4
5
6
7
8
9
10
//證明一級緩存的存在
@test
public void test01(){
 //第一次查詢
 student student = dao.selectstudentbyid(2);
 system.out.println(student);
 //第二次查詢
 student student2 = dao.selectstudentbyid(2);
 system.out.println(student2); 
}

mapper:

?
1
2
3
4
5
<mapper namespace="com.hcx.dao.istudentdao"
  <select id=selectstudentbyid resulttype="com.hcx.beans.student">
   select * from student where id=#{id}
  </select>
</mapper>

控制臺:

執(zhí)行完后,發(fā)現(xiàn)只執(zhí)行了一次從db中的查詢,第二次的結(jié)果是直接輸出的。說明,第二次是從sqlsession緩存中讀取的。

MyBatis查詢緩存實例詳解

2.從緩存讀取數(shù)據(jù)的依據(jù)是sql的id

一級緩存緩存的是相同sql映射id的查詢結(jié)果,而非相同sql語句的查詢結(jié)果。因為mybatis內(nèi)部對于查詢緩存,無論是一級查詢還是二級查詢,其底層均使用一個hashmap實現(xiàn):key為sql的id相關(guān)內(nèi)容,value為從數(shù)據(jù)庫中查詢出的結(jié)果。

mapper:

?
1
2
3
4
5
6
7
8
<mapper namespace="com.hcx.dao.istudentdao">
  <select id=selectstudentbyid resulttype="com.hcx.beans.student">
   select * from student where id=#{id}
  </select>
  <select id="selectstudnetbyid2" resulttype="com.hcx.beans.student">
   select id,name,age,score,birthday from student where id=#{id}
  </select>
</mapper>

dao接口:

?
1
2
3
4
public interface istudentdao { 
 student selectstudentbyid(int id);
 student selectstudentbyid2(int id);
}

測試類:

?
1
2
3
4
5
6
7
8
9
10
11
//證明從一級緩存中讀取數(shù)據(jù)的依據(jù):
//mybatis:sql的id+sql語句
//hibernate:查詢結(jié)果對象的id
@test
public void test02(){
 student student = dao.selectstudentbyid(2);
 system.out.println(student);
 
 student student2 = dao.selectstudentbyid2(2);
 system.out.println(student2); 
}

控制臺:

查看控制臺,發(fā)現(xiàn)第二次查詢結(jié)果與第一次的完全相同,但第二次查詢并沒有從緩存中讀取數(shù)據(jù),而是直接從db中進(jìn)行的查詢。這是因為從緩存讀取數(shù)據(jù)的依據(jù)是查詢sql的映射id,而非查詢結(jié)果。

MyBatis查詢緩存實例詳解

3.增刪改對一級查詢緩存的影響

增刪改操作,無論是否進(jìn)行提交sqlsession.commit(),均會清空一級查詢緩存,使查詢再次從db中select。

測試類:

?
1
2
3
4
5
6
7
8
9
@test
public void test03(){
 student student = dao.selectstudentbyid(2);
 system.out.println(student);
 //增刪改操作都會清空一級緩存,無論是否提交
 dao.insertstudent(new student("趙六",26,96.6));
 student student2 = dao.selectstudentbyid(2);
 system.out.println(student2); 
}

控制臺:

MyBatis查詢緩存實例詳解

二、內(nèi)置二級查詢緩存

mybatis查詢緩存的作用域是根據(jù)映射文件mapper的namespace劃分的,相同namespace的mapper查詢數(shù)據(jù)存放在同一個緩存區(qū)域。不同namespace下的數(shù)據(jù)互不干擾。

無論是一級緩存還是二級緩存,都是按照namespace進(jìn)行分別存放的。但一、二級緩存的不同之處在于,sqlsession一旦關(guān)閉,則sqlsession中的數(shù)據(jù)將不存在,即一級緩存就不復(fù)存在。而二級緩存的生命周期會與整個應(yīng)用同步,與sqlsession是否關(guān)閉無關(guān)。

使用二級緩存的目的,不是共享數(shù)據(jù),因為mybatis從緩存中讀取數(shù)據(jù)的依據(jù)是sql的id,而非查詢出的對象。所以,二級緩存中的數(shù)據(jù)不是為了在多個查詢之間共享(所有查詢中只要查詢結(jié)果中存在該對象的,就直接從緩存中讀取,這是對數(shù)據(jù)的共享,hibernate中的緩存就是為了共享,但mybatis不是),而是為了延長該查詢結(jié)果的保存時間,提高系統(tǒng)性能。

1.二級緩存用法

二級緩存的使用只需要完成兩步:

序列化實體

在mapper映射文件中添加<cache/>標(biāo)簽

1.實體序列化

要求查詢結(jié)果所涉及到的實體類要實現(xiàn)java.io.serializable接口。若該實體類存在父類,或其具有域?qū)傩裕瑒t父類與域?qū)傩灶愐惨獙崿F(xiàn)序列化接口。

?
1
2
3
4
5
6
public class student implements serializable{
 private integer id;
 private string name;
 private int age;
 private double score;
}

2.mapper映射文件中添加<cache/>標(biāo)簽

在mapper映射文件中的<mapper/>標(biāo)簽中添加<cache/>子標(biāo)簽

?
1
2
3
4
5
6
<mapper namespace="com.hcx.dao.istudentdao">
 <cache/>
  <select id=selectstudentbyid resulttype="com.hcx.beans.student">
   select * from student where id=#{id}
  </select>
</mapper>

3.二級緩存的配置

為<cache/>標(biāo)簽添加一些相關(guān)屬性設(shè)置,可以對二級緩存的運行性能進(jìn)行控制。若不指定設(shè)置,則均保持默認(rèn)值。

?
1
2
<cache eviction="ifio" flushinterval="10800000"
  readonly="true" size="512"/>

eviction:逐出策略。當(dāng)二級緩存中的對象達(dá)到最大值時,就需要通過逐出策略將緩存中的對象移出緩存。默認(rèn)為lru。常用的策略有fifo和lru

flushinterval:刷新緩存的時間間隔,單位毫秒。這里的刷新緩存即清空緩存。一般不指定,即當(dāng)執(zhí)行增刪改時刷新緩存。

readonly:設(shè)置緩存中數(shù)據(jù)是否只讀。只讀的緩存會給所有調(diào)用者返回緩存對象的相同實例,因此這些對象不能被修改,這提供了很重要的性能優(yōu)勢。但讀寫的緩存會返回緩存對象的拷貝。這會慢一些,但是安全,因此默認(rèn)是false。
size:二級緩存中可以存放的最多對象個數(shù)。默認(rèn)為1024個。

2.二級緩存的存在性證明

對于映射文件中的同一個查詢,肯定是同一個namespace中的查詢。在一次查詢后,將sqlsession關(guān)閉,再進(jìn)行一次相同查詢,發(fā)現(xiàn)并沒有到db中進(jìn)行select查詢,說明二級緩存是存在的。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
//證明二級緩存的存在
@test
public void test01(){
 //第一次查詢
 student student = dao.selectstudentbyid(2);
 system.out.println(student);
 sqlsession.close();
 sqlsession = mybatisutils.getsqlsession();
 dao = sqlsession.getmapper(istudentdao.class);
 //第二次查詢
 student student2 = dao.selectstudentbyid(2);
 system.out.println(student2); 
}

查看控制臺:

cache hit ratio表示緩存命中率。開啟二級緩存后,每執(zhí)行一次查詢,系統(tǒng)都會計算一次二級緩存的命中率。第一次查詢也是先從緩存中查詢,只不過緩存中一定是沒有的。所以會再從db中查詢。由于二級緩存中不存在該數(shù)據(jù),所以命中率為0.但第二次查詢是從二級緩存中讀取的,所以這一次的命中率為1/2=0.5。當(dāng)然,若有第三次查詢,則命中率為1/3=0.66

MyBatis查詢緩存實例詳解

3.增刪改對二級緩存的影響

增刪改操作,無論是否進(jìn)行提交sqlsession.commit(),均會清空一級、二級緩存,使查詢再次從db中select。

測試類:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
@testpublic void test02(){
 //第一次查詢
 student student = dao.selectstudentbyid(2);
 system.out.println(student);
 sqlsession.close();
 sqlsession = mybatisutils.getsqlsession();
 dao = sqlsession.getmapper(istudentdao.class);
 //插入
 dao.insertstudent(new student("",0,0));
 //第二次查詢
 student student2 = dao.selectstudentbyid(2);
 system.out.println(student2); 
}

控制臺:

注意,在第二次查詢時的緩存命中率為0.5,但還是從db中查詢了。說明在緩存中與該查詢相對應(yīng)的key是存在的,但其value被清空。而value被清空的原因是前面執(zhí)行了對db的增刪改操作,所以不會從緩存中直接將null值返回,而是從db中進(jìn)行查詢。

MyBatis查詢緩存實例詳解

說明:

二級緩存的清空,實質(zhì)上是對所查找key對應(yīng)的value置為null,而非將<key,value>對,即entry對象刪除。

從db中進(jìn)行select查詢的條件是:緩存中根本不存在這個key或者緩存中存在該key所對應(yīng)的entry對象,但value為null。

設(shè)置增刪改操作不刷新二級緩存:

若要使某個增、刪或改操作不清空二級緩存,則需要在其<insert/>或<delete/>或<update/>中添加屬性flushcache="false",默認(rèn)為true。

?
1
2
3
<insert id="insertstudent" flushcache="false">
  insert into student(name,age,score) values(#{name},#{age},#{score})
 </insert>

4.二級緩存的關(guān)閉

二級緩存默認(rèn)為開啟狀態(tài)。若要將其關(guān)閉,則需要進(jìn)行相關(guān)設(shè)置。
根據(jù)關(guān)閉的范圍大小,可以分為全局關(guān)閉和局部關(guān)閉

1.全局關(guān)閉(在配置文件中設(shè)置)

全局關(guān)閉是指整個應(yīng)用的二級緩存全部關(guān)閉,所有查詢均不使用二級緩存。全局開關(guān)設(shè)置在主配置文件的全局設(shè)置<settings/>中,該屬性為cacheenabled,設(shè)置為false,則關(guān)閉;設(shè)置為true,則開啟,默認(rèn)值為true。即二級緩存默認(rèn)是開啟的。

?
1
2
3
4
<!-- 關(guān)閉二級緩存 -->
<settings>
 <setting name="cacheenabled" value="false"/>
</settings>

2.局部關(guān)閉(在映射文件的每個select中設(shè)置)

局部關(guān)閉指整個應(yīng)用的二級緩存是開啟的,但只是針對某個<select/>查詢,不使用二級緩存。此時可以單獨只關(guān)閉該<select/>標(biāo)簽的二級緩存。

在該要關(guān)閉二級緩存的<select/>標(biāo)簽中,將其屬性usecache設(shè)置為false,即可關(guān)閉該查詢的二級緩存。該屬性默認(rèn)為true,即每個<select/>查詢的二級緩存默認(rèn)是開啟的。

?
1
2
3
4
<!--usecache="false"對當(dāng)前sql的二級緩存的局部關(guān)閉 -->
 <select id=selectstudentbyid usecache="false" resulttype="com.hcx.beans.student">
  select * from student where id=#{id}
 </select>

5.二級緩存的使用原則

1.只能在一個命名空間下使用二級緩存

由于二級緩存中的數(shù)據(jù)是基于namespace的,即不同namespace中的數(shù)據(jù)互不干擾。在多個namespace中若均存在對同一個表的操作,那么這多個namespace中的數(shù)據(jù)可能就會出現(xiàn)不一致現(xiàn)象。

2.在單表上使用二級緩存

如果一個表與其它表有關(guān)聯(lián)關(guān)系,那么久非常有可能存在多個namespace對同一數(shù)據(jù)的操作。而不同namespace中的數(shù)據(jù)互補干擾,所以就有可能出現(xiàn)多個namespace中的數(shù)據(jù)不一致現(xiàn)象。

3.查詢多于修改時使用二級緩存

在查詢操作遠(yuǎn)遠(yuǎn)多于增刪改操作的情況下可以使用二級緩存。因為任何增刪改操作都將刷新二級緩存,對二級緩存的頻繁刷新將降低系統(tǒng)性能。

三、ehcache二級查詢緩存

mybatis允許使用第三方緩存產(chǎn)品。ehcache就是其中一種。

注意:使用ehcache二級緩存,實體類無需實現(xiàn)序列化接口。

1.導(dǎo)入jar包

MyBatis查詢緩存實例詳解

2.添加ehcache.xml

解壓ehcache的核心jar包ehcache-core-2.6.8.jar,將其中的一個配置文件ehcache-failsafe.xml直接放到項目的src目錄下,并更名為ehcache.xml

(1)<diskstore/>標(biāo)簽

指定一個文件目錄,當(dāng)內(nèi)存空間不夠,需要將二級緩存中數(shù)據(jù)寫到硬盤上時,會寫到這個指定目錄中。其值一般為java.io.tmpdir,表示當(dāng)前系統(tǒng)的默認(rèn)文件臨時目錄。

MyBatis查詢緩存實例詳解

當(dāng)前文件系統(tǒng)的默認(rèn)文件臨時目錄,可以通過system.property()方法查看:

?
1
2
3
4
5
@test
public void test(){
 string path = system.getproperty("java.io.tmpdir");
 system.out.println(path);
}

(2)<defaultcache/>標(biāo)簽

MyBatis查詢緩存實例詳解

MyBatis查詢緩存實例詳解

3.啟用ehcache緩存機制

在映射文件的mapper中的<cache/>中通過type指定緩存機制為ehcache緩存。默認(rèn)為mybatis內(nèi)置的二級緩存org.apache.ibatis.cache.impl.perpetualcache。

?
1
2
3
4
5
6
<mapper namespace="com.hcx.dao.istudentdao">
 <cache type="org.mybatis.caches.ehcache.ehcachecache"/>
  <select id=selectstudentbyid resulttype="com.hcx.beans.student">
   select * from student where id=#{id}
  </select>
</mapper>

4.ehcache在不同mapper中的個性化設(shè)置

在ehcache.xml中設(shè)置的屬性值,會對該項目中所有使用ehcache緩存機制的緩存區(qū)域起作用。一個項目中可以有多個mapper,不同的mapper有不同的緩存區(qū)域。對于不同緩存區(qū)域也可進(jìn)行專門針對于當(dāng)前區(qū)域的個性設(shè)置,可通過指定不同mapper的<cache>屬性值來設(shè)置。

<cache>屬性值的優(yōu)先級高于ehcache.xml中的屬性值。

?
1
2
3
4
5
6
<mapper namespace="com.hcx.dao.istudentdao">
 <cache type="org.mybatis.caches.ehcache.ehcachecache"/>
   <property name="maxelementsinmemory" value="5000"/>
   <property name="timetoidleseconds" value="240"/>
 </cache>
</mapper>

以上所述是小編給大家介紹的mybatis查詢緩存實例詳解,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復(fù)大家的。在此也非常感謝大家對服務(wù)器之家網(wǎng)站的支持!

原文鏈接:http://www.jianshu.com/p/90a34862dcdc

延伸 · 閱讀

精彩推薦
Weibo Article 1 Weibo Article 2 Weibo Article 3 Weibo Article 4 Weibo Article 5 Weibo Article 6 Weibo Article 7 Weibo Article 8 Weibo Article 9 Weibo Article 10 Weibo Article 11 Weibo Article 12 Weibo Article 13 Weibo Article 14 Weibo Article 15 Weibo Article 16 Weibo Article 17 Weibo Article 18 Weibo Article 19 Weibo Article 20 Weibo Article 21 Weibo Article 22 Weibo Article 23 Weibo Article 24 Weibo Article 25 Weibo Article 26 Weibo Article 27 Weibo Article 28 Weibo Article 29 Weibo Article 30 Weibo Article 31 Weibo Article 32 Weibo Article 33 Weibo Article 34 Weibo Article 35 Weibo Article 36 Weibo Article 37 Weibo Article 38 Weibo Article 39 Weibo Article 40
主站蜘蛛池模板: 中文字幕在线观看第一页 | 91尤物网站网红尤物福利 | 久久av网| 国产精品一区二 | 欧美一级片 | 久久人人爽爽爽人久久久 | 国产精品美女久久久久久久久久久 | 国产精品久久久久久久久久99 | yy6080久久伦理一区二区 | 天堂av资源| a在线观看| 久久免费精品 | 亚洲国产成人91精品 | 国产免费久久精品 | 日本高清中文字幕 | 亚洲青涩在线 | 中文一区 | 337p亚洲欧洲 | 国产精品亚洲一区二区三区 | 亚洲精品一区二区 | 日韩欧美的一区二区 | www欧美| 久久精品免费观看 | 日韩视频一区 | 影音先锋男人网 | 日韩在线免费 | 色欧美亚洲 | 欧美成人性生活 | 综合久久综合 | 国产精品久久久久久久午夜片 | 女教师高潮叫床视频在线观看 | 99精品欧美一区二区三区 | 亚洲精品电影在线观看 | 午夜在线电影 | 欧美亚洲综合久久 | 日本三级电影网站 | 日韩有码在线观看 | 日日夜夜精品免费视频 | 在线一区二区三区 | 久久影视精品 | 国产在线精品一区二区 |