mybatis?查詢方式與效率高低對比
mybatis查詢方式與效率高低
<!-- ? ? ?一對一關(guān)聯(lián)查詢 ? ? ?select s.id,s.name,s.age,t.name tname ?from student s,teacher t where s.tid=t.id; ? ? ? --> ? ? <!-- ? ? ? ? 關(guān)聯(lián)的嵌套 Select 查詢 ? ? 問題: ? ? ? ? 這種方式雖然很簡單,但在大型數(shù)據(jù)集或大型數(shù)據(jù)表上表現(xiàn)不佳。這個問題被稱為“N+1 查詢問題”。 概括地講,N+1 查詢問題是這樣子的: ? ? ? ? ? ? 你執(zhí)行了一個單獨(dú)的 SQL 語句來獲取結(jié)果的一個列表(就是“+1”)。 ? ? ? ? ? ? 對列表返回的每條記錄,你執(zhí)行一個 select 查詢語句來為每條記錄加載詳細(xì)信息(就是“N”)。 ? ? 解決: ? ? ? ? MyBatis 能夠?qū)@樣的查詢進(jìn)行延遲加載,因此可以將大量語句同時運(yùn)行的開銷分散開來。 ? ? ? ? (例如: 我需要teacher這個對象的時候就會進(jìn)行加載,如果不需要就不會立即加載(延遲加載)) ? ? ? ? ?然而,如果你加載記錄列表之后立刻就遍歷列表以獲取嵌套的數(shù)據(jù),就會觸發(fā)所有的延遲加載查詢,性能可能會變得很糟糕。 ? ? --> ? ? <!-- ?關(guān)聯(lián)的嵌套 Select 查詢 ?--> ? ? <resultMap id="studentMap" type="student"> ? ? ? ? <id property="id" column="id"/> ? ? ? ? <result property="name" column="name"/> ? ? ? ? <result property="age" column="age"/> ? ? ? ? <association property="teacher" column="tid" javaType="teacher" select="selectTeacherById"> ? ? ? ? </association> ? ? </resultMap> ? ? <select id="findAll" resultMap="studentMap"> ? ? ? ? select * from student; ? ? </select> ? ? <select id="selectTeacherById" parameterType="int" resultType="teacher" ?> ? ? ? ? select * from ?teacher where id=#{id}; ? ? </select> ? ? <!-- ? ? ? ? 關(guān)聯(lián)的嵌套 ?結(jié)果映射 ?? ??? ?將結(jié)果直接映射 到實(shí)體類中 ? ? ? ? 第二種 方式效率比第一種 速度更高 ? ? ?--> ? ? <resultMap id="studentMap1" type="student"> ? ? ? ? <id property="id" column="id"/> ? ? ? ? <result property="name" column="name"/> ? ? ? ? <result property="age" column="age"/> ? ? ? ? <association property="teacher" javaType="teacher"> ? ? ? ? ? ? <id property="id" column="tid"/> ? ? ? ? ? ? <result property="name" column="tname"/> ? ? ? ? </association> ? ? </resultMap> ? ? <select id="selectAll" resultMap="studentMap1"> ? ? ? ? select s.id,s.name,s.age,t.name tname ,t.id tid from student s,teacher t where s.tid=t.id; ? ? </select> ------------------------------------------------------------------ <!-- ?一對多 ?關(guān)聯(lián)嵌套 ?結(jié)果映射 ? ?ofType 將數(shù)據(jù)封裝到指定的泛型 ?--> ? ? <resultMap id="teacherMap" type="teacher"> ? ? ? ? <id property="id" column="id"/> ? ? ? ? <result property="name" column="name"/> ? ? ? ? <collection property="students" ofType="student" > ? ? ? ? ? ? <id property="id" column="sid"/> ? ? ? ? ? ? <result property="name" column="sname"/> ? ? ? ? ? ? <result property="age" column="sage"/> ? ? ? ? ? ? <result property="tid" column="stid"/> ? ? ? ? </collection> ? ? </resultMap> ? ? <select id="selectTeacherById" ?parameterType="int" ?resultMap="teacherMap"> ? ? ? ? ?select t.id ,t.name,s.id sid,s.name sname,s.age sage,s.tid stid ? ? ? ? ?from student s ,teacher t ? ? ? ? ?where s.tid=t.id and t.id=1; ? ? </select>
mybatis提高查詢效率的方式
緩存機(jī)制
1 一級緩存:
當(dāng)mysql連續(xù)執(zhí)行兩次select * from table where id =1;第一次會執(zhí)行sql語句查詢數(shù)據(jù)庫,然后保存到sqlsession緩存,第二次查詢會先從緩存里查找,有的話直接返回不會執(zhí)行sql.
但是如果兩次sql中間增加一次commit操作(insert,delete,update),如:
select * from table where id =1 update table set name = zjw where id =1; select * from table where id =1
這個時候第一次查詢依然會執(zhí)行sql查詢數(shù)據(jù)庫,但是在執(zhí)行完update后會清空sqlsession里的緩存,原因是避免臟讀,
所以第二次select在緩存里找不到數(shù)據(jù),又會執(zhí)行sql查詢數(shù)據(jù)庫。
2 二級緩存:
二級緩存是基于mapper文件的namaspace,對該mapper的所有sqlsession都共享一個二級緩存,如果兩個mapper的namespace一致,則兩個mapper的所有sqlsession共用一個二級緩存,
步驟:
在全局配置文件mybatis-configuration.xml加入
其次在mapper文件開啟緩存 type里面是緩存類。如果不寫是默認(rèn)的mabatis緩存類,自定義緩存類必須實(shí)現(xiàn)cache接口
需要緩存的pojo實(shí)體類要實(shí)現(xiàn)serializable接口,因?yàn)樵诰彺嬷腥〕鰯?shù)據(jù)映射到pojo類需要反序列化。
不同的兩個sqlsession查詢走二級緩存,但是如果其中有一個commit操作,為避免臟讀二級緩存還是會被清空。
在每個sql語句上使用useCache=true/false是否使用緩存,flushcache=true/false是否刷新緩存 ,在每次的commit后默認(rèn)刷新緩存。
懶加載
Mybatis中resultmap可以實(shí)現(xiàn)高級映射,association一對一,Collection一對多具有延遲加載功能
在collection或association中fetchtype=lazy,即為懶加載
在查詢主表時,不會把子集查出來,直到子集用到的情況才會查出子集。
總結(jié)
以上為個人經(jīng)驗(yàn),希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
分布式服務(wù)Dubbo+Zookeeper安全認(rèn)證實(shí)例
下面小編就為大家分享一篇分布式服務(wù)Dubbo+Zookeeper安全認(rèn)證實(shí)例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2017-12-12IDEA中Javaweb項(xiàng)目圖片加載不出來解決方案
在IDEA中能夠正常的預(yù)覽到圖片,但是在生成項(xiàng)目的war包時,項(xiàng)目的目錄結(jié)構(gòu)卻會發(fā)生變化,所以無法訪問圖片,本文主要介紹了IDEA中Javaweb項(xiàng)目圖片加載不出來解決方案,感興趣的可以了解一下2023-10-10springboot結(jié)合mysql主從來實(shí)現(xiàn)讀寫分離的方法示例
這篇文章主要介紹了springboot結(jié)合mysql主從來實(shí)現(xiàn)讀寫分離的方法示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-04-04Java實(shí)現(xiàn)PDF轉(zhuǎn)為線性PDF詳解
線性化PDF文件是PDF文件的一種特殊格式,可以通過Internet更快地進(jìn)行查看。本文將通過后端Java程序?qū)崿F(xiàn)將PDF文件轉(zhuǎn)為線性化PDF。感興趣的可以了解一下2021-12-12Java設(shè)計(jì)模式之單態(tài)模式(Singleton模式)介紹
這篇文章主要介紹了Java設(shè)計(jì)模式之單態(tài)模式(Singleton模式)介紹,本文講解了如何使用單例模式、使用單例模式注意事項(xiàng)等內(nèi)容,需要的朋友可以參考下2015-03-03淺談Spring Cloud Eureka 自我保護(hù)機(jī)制
這篇文章主要介紹了淺談Spring Cloud Eureka 自我保護(hù)機(jī)制,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-06-06springboot學(xué)習(xí)筆記之 profile多環(huán)境配置切換的實(shí)現(xiàn)方式
這篇文章主要介紹了springboot profile多環(huán)境配置切換的實(shí)現(xiàn)方式,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價值 ,需要的朋友可以參考下2019-07-07SpringSecurity的防Csrf攻擊實(shí)現(xiàn)代碼解析
這篇文章主要介紹了SpringSecurity的防Csrf攻擊實(shí)現(xiàn)代碼解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-03-03