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