mybatis?resultMap之collection聚集兩種實(shí)現(xiàn)方式
最近做得項(xiàng)目用到了MyBatis處理一對(duì)多的映射關(guān)系,下面的兩個(gè)方法中用到了集合的嵌套查詢(xún)方法,下面仔細(xì)學(xué)習(xí)一下這兩種方式
聚集元素用來(lái)處理“一對(duì)多”的關(guān)系。需要指定映射的Java實(shí)體類(lèi)的屬性,屬性的javaType(一般為ArrayList);列表中對(duì)象的類(lèi)型ofType(Java實(shí)體類(lèi));對(duì)應(yīng)的數(shù)據(jù)庫(kù)表的列名稱(chēng);
不同情況需要告訴MyBatis 如何加載一個(gè)聚集。MyBatis 可以用兩種方式加載:
select: 執(zhí)行一個(gè)其它映射的SQL 語(yǔ)句返回一個(gè)Java實(shí)體類(lèi)型。較靈活但會(huì)將執(zhí)行多次嵌套的SQL語(yǔ)句。
resultMap: 使用一個(gè)嵌套的結(jié)果映射來(lái)處理通過(guò)join查詢(xún)結(jié)果集,映射成Java實(shí)體類(lèi)型。
兩種加載方式格式如下:
集合的嵌套查詢(xún)(select)
<collection property="Java屬性名" ofType="另一Java類(lèi)名" javaType="ArrayList" column="關(guān)聯(lián)主鍵ID(用于嵌套查詢(xún)SQL語(yǔ)句傳入?yún)?shù),多個(gè)用逗號(hào)分開(kāi))" select="另一個(gè)select映射SQL的ID"/> <select parameterType="int" resultType="另一Java類(lèi)名" id="另一個(gè)select映射SQL的ID"> SQL語(yǔ)句 </select>
<resultMap id="blogResult" type="Blog"> <collection property="posts" javaType=”ArrayList” column="blog_id" ofType="Post" select="selectPostsForBlog"/> </resultMap> <select id="selectBlog" parameterType="int" resultMap="blogResult"> SELECT * FROM BLOG WHERE ID = #{id} </select> <select id="selectPostsForBlog" parameterType="int" resultType="Author"> SELECT * FROM POST WHERE BLOG_ID = #{id} </select>
注意:column屬性的值必須與相應(yīng)的SQL查詢(xún)語(yǔ)句中的列名相同。MyBatis會(huì)將第一條SQL語(yǔ)句查詢(xún)出來(lái)的該列的值用于所聚集的SQL映射語(yǔ)句的入?yún)ⅰR虻谝粭lSQL語(yǔ)句查詢(xún)出來(lái)的每個(gè)該列的值都將用于執(zhí)行另一個(gè)SQL語(yǔ)句,所以聚集的SQL語(yǔ)句將被多次執(zhí)行
雖然這個(gè)方法簡(jiǎn)單,但是對(duì)于大數(shù)據(jù)集或列表查詢(xún),就不盡如人意了。這個(gè)問(wèn)題被稱(chēng)為“N+1 選擇問(wèn)題”(N+1 Selects Problem)。概括地說(shuō),N+1選擇問(wèn)題是這樣產(chǎn)生的:
您執(zhí)行單條SQL語(yǔ)句去獲取一個(gè)列表的記錄( “+1”)。
對(duì)列表中的每一條記錄,再執(zhí)行一個(gè)聯(lián)合select 語(yǔ)句來(lái)加載每條記錄更加詳細(xì)的信息(“N”)。
這個(gè)問(wèn)題會(huì)導(dǎo)致成千上萬(wàn)的SQL語(yǔ)句的執(zhí)行,因此并非總是可取的。
上面的例子,MyBatis可以使用延遲加載這些查詢(xún),因此這些查詢(xún)立馬可節(jié)省開(kāi)銷(xiāo)。然而,如果您加載一個(gè)列表后立即迭代訪(fǎng)問(wèn)嵌套的數(shù)據(jù),這將會(huì)調(diào)用所有的延遲加載,因此性能會(huì)變得非常糟糕。
鑒于此,這有另外一種方式。
集合的嵌套結(jié)果集(Nested Results for Collection)
<resultMap id="resultMap的ID" type="Java類(lèi)名"> <collection property="Java屬性名" ofType="另一Java類(lèi)名" javaType="ArrayList" resultMap="另一resultMap的ID"/> </resultMap> <resultMap="另一resultMap的ID" type="另一Java類(lèi)名"> <id property="id" column="關(guān)聯(lián)主鍵ID"/> .... </resultMap>
<select id="selectBlog" parameterType="int" resultMap="blogResult"> select B.id as blog_id, B.title as blog_title, B.author_id as blog_author_id, P.id as post_id, P.subject as post_subject, P.body as post_body, from Blog B left outer join Post P on B.id = P.blog_id where B.id = #{id} </select>
同樣,我們把Blog和Post兩張表連接在一起,并且也保證列標(biāo)簽名在映射的時(shí)候是唯一且無(wú)歧義的?,F(xiàn)在將Blog和Post的集合映射在一起是多么簡(jiǎn)單:
<resultMap id="blogResult" type="Blog"> <id property="id" column="blog_id" /> <result property="title" column="blog_title"/> <collection property="posts" ofType="Post"> <id property="id" column="post_id"/> <result property="subject" column="post_subject"/> <result property="body" column="post_body"/> </collection> </resultMap>
再次強(qiáng)調(diào)一下,id 元素是非常重要的。
如果希望結(jié)果映射有更好的可重用性,您可以使用下面的方式:
<resultMap id="blogResult" type="Blog"> <id property="id" column="blog_id" /> <result property="title" column="blog_title"/> <collection property="posts" ofType="Post" resultMap="blogPostResult"/> </resultMap> <resultMap id="blogPostResult" type="Post"> <id property="id" column="post_id"/> <result property="subject" column="post_subject"/> <result property="body" column="post_body"/> </resultMap>
注意:column屬性的值必須與相應(yīng)的SQL查詢(xún)語(yǔ)句的列名一樣。
到此這篇關(guān)于mybatis resultMap之collection聚集兩種實(shí)現(xiàn)方式的文章就介紹到這了,更多相關(guān)mybatis resultMap collection聚集內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- mybatis collection關(guān)聯(lián)查詢(xún)多個(gè)參數(shù)方式
- MyBatis使用嵌套查詢(xún)collection和association的實(shí)現(xiàn)
- mybatis中association和collection的使用與區(qū)別
- MyBatis的collection和association的使用解讀
- Mybatis中一對(duì)多(collection)和一對(duì)一(association)的組合查詢(xún)使用
- Mybatis使用Collection屬性的示例代碼
- Mybatis的collection三層嵌套查詢(xún)方式(驗(yàn)證通過(guò))
- mybatis?collection和association的區(qū)別解析
- MyBatis中<collection>標(biāo)簽的多種用法
相關(guān)文章
java中如何判斷JSONObject是否存在某個(gè)Key
這篇文章主要介紹了java中如何判斷JSONObject是否存在某個(gè)Key,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-07-07Spring通過(guò)@Lazy解決構(gòu)造方法形式的循環(huán)依賴(lài)問(wèn)題
這篇文章主要給大家介紹了Spring如何通過(guò)@Lazy解決構(gòu)造方法形式的循環(huán)依賴(lài)問(wèn)題,文中有詳細(xì)的代碼示例,對(duì)大家的學(xué)習(xí)活工作有一定的幫助,具有一定的參考價(jià)值,需要的朋友可以參考下2023-10-10Java線(xiàn)程同步及實(shí)現(xiàn)方法詳解
這篇文章主要介紹了Java線(xiàn)程同步及實(shí)現(xiàn)方法詳解,當(dāng)我們有多個(gè)線(xiàn)程要同時(shí)訪(fǎng)問(wèn)一個(gè)變量或?qū)ο髸r(shí),如果這些線(xiàn)程中既有讀又有寫(xiě)操作時(shí),就會(huì)導(dǎo)致變量值或?qū)ο蟮臓顟B(tài)出現(xiàn)混亂,從而導(dǎo)致程序異常,需要的朋友可以參考下2023-11-11使用JMeter進(jìn)行接口高并發(fā)測(cè)試的實(shí)現(xiàn)
本文主要介紹了使用JMeter進(jìn)行接口高并發(fā)測(cè)試的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-04-04Java回調(diào)函數(shù)原理實(shí)例與代理模式的區(qū)別講解
今天小編就為大家分享一篇關(guān)于Java回調(diào)函數(shù)原理實(shí)例與代理模式的區(qū)別講解,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧2019-02-02