您好,登錄后才能下訂單哦!
案例:https://github.com/sun2shadow/simpleMybatis
resultMap 元素是 MyBatis 中最重要最強(qiáng)大的元素。
先看一個(gè)簡單的映射:
<select id="selectUsers" resultType="map"> select id, username, hashedPassword from some_table where id = #{id} </select>
它把所有的列映射到HashMap的主鍵上.但是實(shí)踐中經(jīng)常把resultType類型制定為JavaBeans或POJOs,如以下語句:
<select id="selectUsers" resultType="com.someapp.model.User"> select id, username, hashedPassword from some_table where id = #{id} </select>
高級映射是開發(fā)中常用的形式:
resultMap概念視圖:
constructor - 類在實(shí)例化時(shí),用來注入結(jié)果到構(gòu)造方法中
idArg - ID 參數(shù);標(biāo)記結(jié)果作為 ID 可以幫助提高整體效能
arg - 注入到構(gòu)造方法的一個(gè)普通結(jié)果
id – 一個(gè) ID 結(jié)果;標(biāo)記結(jié)果作為 ID 可以幫助提高整體效能
result – 注入到字段或 JavaBean 屬性的普通結(jié)果
association – 一個(gè)復(fù)雜的類型關(guān)聯(lián);許多結(jié)果將包成這種類型
嵌入結(jié)果映射 – 結(jié)果映射自身的關(guān)聯(lián),或者參考一個(gè)
collection – 復(fù)雜類型的集
嵌入結(jié)果映射 – 結(jié)果映射自身的集,或者參考一個(gè)
discriminator – 使用結(jié)果值來決定使用哪個(gè)結(jié)果映射
嵌入結(jié)果映射 – 這種情形結(jié)果也映射它本身,因此可以包含很多相 同的元素,或者它可以參照一個(gè)外部的結(jié)果映射。
case – 基于某些值的結(jié)果映射
屬性 | 描述 |
---|---|
id | 當(dāng)前命名空間中的一個(gè)唯一標(biāo)識,用于標(biāo)識一個(gè)result map. |
type | 類的全限定名, 或者一個(gè)類型別名 (內(nèi)置的別名可以參考上面的表格). |
autoMapping | 如果設(shè)置這個(gè)屬性,MyBatis將會為這個(gè)ResultMap開啟或者關(guān)閉自動映射。這個(gè)屬性會覆蓋全局的屬性autoMappingBehavior。默認(rèn)值為:unset。 |
<resultMap id="detailedBlogResultMap" type="Blog"> </resultMap>
Id&result
<id property="id" column="post_id"/> <result property="subject" column="post_subject"/>
id 和 result 都映射一個(gè)單獨(dú)列的值到簡單數(shù)據(jù)類型(字符 串,整型,雙精度浮點(diǎn)數(shù),日期等)的單獨(dú)屬性或字段
屬性 | 描述 |
---|---|
property | 映射到列結(jié)果的字段或?qū)傩?。如果匹配的是存在?和給定名稱相同 的 JavaBeans 的屬性,那么就會使用。否則 MyBatis 將會尋找給定名稱 property 的字段。這兩種情形你可以使用通常點(diǎn)式的復(fù)雜屬性導(dǎo)航。比如,你 可以這樣映射一些東西: “username” ,或者映射到一些復(fù)雜的東西: “address.street.number” 。 |
column | 從數(shù)據(jù)庫中得到的列名,或者是列名的重命名標(biāo)簽。這也是通常和會 傳遞給 resultSet.getString(columnName)方法參數(shù)中相同的字符串。 |
javaType | 一個(gè) Java 類的完全限定名,或一個(gè)類型別名(參考上面內(nèi)建類型別名 的列表) 。如果你映射到一個(gè) JavaBean,MyBatis 通??梢詳喽愋?。 然而,如果你映射到的是 HashMap,那么你應(yīng)該明確地指定 javaType 來保證所需的行為。 |
jdbcType | 在這個(gè)表格之后的所支持的 JDBC 類型列表中的類型。JDBC 類型是僅 僅需要對插入,更新和刪除操作可能為空的列進(jìn)行處理。這是 JDBC jdbcType 的需要,而不是 MyBatis 的。如果你直接使用 JDBC 編程,你需要指定 這個(gè)類型-但僅僅對可能為空的值。 |
typeHandler | 我們在前面討論過默認(rèn)的類型處理器。使用這個(gè)屬性,你可以覆蓋默 認(rèn)的類型處理器。這個(gè)屬性值是類的完全限定名或者是一個(gè)類型處理 器的實(shí)現(xiàn),或者是類型別名。 |
關(guān)聯(lián):連表查詢時(shí)需要關(guān)聯(lián)映射關(guān)系.property:blog中author變量,column表的author的外建,javaType關(guān)聯(lián)的entity
<association property="author" column="blog_author_id" javaType="Author"> <id property="id" column="author_id"/> <result property="username" column="author_username"/> </association>
通過映射關(guān)系來告訴MyBatis如何加載關(guān)聯(lián)關(guān)系,MyBatis提供了2中方式:
嵌套查詢:通過執(zhí)行另外一個(gè) SQL 映射語句來返回預(yù)期的復(fù)雜類型。
嵌套結(jié)果:使用嵌套結(jié)果映射來處理重復(fù)的聯(lián)合結(jié)果的子集。首先,然讓我們來查看這個(gè)元素的屬性。所有的你都會看到,它和普通的只由 select 和
resultMap 屬性的結(jié)果映射不同。
關(guān)聯(lián)的嵌套查詢:
<resultMap id="blogResult" type="Blog"> <association property="author" column="author_id" javaType="Author" select="selectAuthor"/> </resultMap> <select id="selectBlog" resultMap="blogResult"> SELECT * FROM BLOG WHERE ID = #{id} </select> <select id="selectAuthor" resultType="Author"> SELECT * FROM AUTHOR WHERE ID = #{id} </select>
一個(gè)來加載博客,另外一個(gè)來加載作者,這種方式最大的問題就是N+1查詢問題,查詢一條博客有N個(gè)作者需要查詢作者表N次.
關(guān)聯(lián)的嵌套結(jié)果:
先看一個(gè)這樣的語句:查詢blog的作者和聯(lián)合作者,作者和聯(lián)合作者的id不能都叫author_id,否則會引起沖突.
<select id="selectBlog" resultMap="blogResult"> select B.id as blog_id, B.title as blog_title, A.id as author_id, A.username as author_username, A.password as author_password, A.email as author_email, A.bio as author_bio, CA.id as co_author_id, CA.username as co_author_username, CA.password as co_author_password, CA.email as co_author_email, CA.bio as co_author_bio from Blog B left outer join Author A on B.author_id = A.id left outer join Author CA on B.co_author_id = CA.id where B.id = #{id}</select>
首先定義author的結(jié)果映射:
<resultMap id="authorResult" type="Author"> <id property="id" column="author_id"/> <result property="username" column="author_username"/> <result property="password" column="author_password"/> <result property="email" column="author_email"/> <result property="bio" column="author_bio"/> </resultMap>
其次定義blog的resultMap,通過columnPrefix來指定前綴以此來區(qū)分是主作者還是聯(lián)合作者.
<resultMap id="blogResult" type="Blog"> <id property="id" column="blog_id" /> <result property="title" column="blog_title"/> <association property="author" resultMap="authorResult" /> <association property="coAuthor" resultMap="authorResult" columnPrefix="co_" /> </resultMap>
看完了關(guān)聯(lián),再來看集合就容易多了,基本上是相似的.
private List<Post> posts;
這種關(guān)系就需要用到集合,通過ofType指定,列表內(nèi)數(shù)據(jù)的類型是Post.
<select id="selectBlog" 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>
上面這個(gè)查詢需要映射的關(guān)系如下:collection 中property屬性是blog中的變量posts,看上面的變量聲明
<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>
下面來簡單的說明一下鑒別器:根據(jù)查詢結(jié)果的不同來選擇不同的映射器.
鑒別器這個(gè)例子比較有意思,查詢車輛信息,返回不同類型的車輛,有轎車,貨車,SUV等不同類型有不同的映射結(jié)果.
<resultMap id="vehicleResult" type="Vehicle"> <id property="id" column="id" /> <result property="vin" column="vin"/> <result property="year" column="year"/> <result property="make" column="make"/> <result property="model" column="model"/> <result property="color" column="color"/> <discriminator javaType="int" column="vehicle_type"> <case value="1" resultMap="carResult"/> <case value="2" resultMap="truckResult"/> <case value="3" resultMap="vanResult"/> <case value="4" resultMap="suvResult"/> </discriminator> </resultMap>
如果類型是car的話,則按照carResult來映射結(jié)果:
<resultMap id="carResult" type="Car"> <result property="doorCount" column="door_count" /> </resultMap>
這種情況下只有 doorCount 屬性會被加載.如果 Car 是一個(gè) Vehicle 實(shí)例。因此,我們想要剩余的屬性也被加載。我們設(shè)置的結(jié)果映射的 簡單改變?nèi)缦隆?/p>
<resultMap id="carResult" type="Car" extends="vehicleResult"> <result property="doorCount" column="door_count" /> </resultMap>
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。