黑莲技术资源论坛

作者: wuwuqiwu
查看: 84|回复: 0

2K字詳解︰MyBatis中核心要點Select resultType和resultMap

2K字詳解︰MyBatis中核心要點Select resultType和resultMap

[复制链接]
wuwuqiwu | 显示全部楼层 发表于: 2022-9-22 12:55:00
wuwuqiwu 发表于: 2022-9-22 12:55:00 | 显示全部楼层 |阅读模式
查看: 84|回复: 0
MyBatis常用動態標簽大全見上述URL,它們大概分為如下四類︰

標簽
作用
使用場景
foreach
循環語句
批量添加或者批量查詢
if
條件判斷語句
單條件分支判斷
choose、when、otherwise
類似 Java 中的 switch、case、default 語句
多條件分支判斷
trim、where、set
輔助標簽
用于處理一些條件查詢

€€€€在MyBatis中有一個ResultMap標簽,它是為了映射select標簽查詢出來的結果集,其主要作用是將實體類中的字段與數據庫表中的字段進行關聯映射。

前言

€€€€Mybatis 中 select 標簽有兩個屬性 resultType 和 resultMap,用于在mapper.xml文件中配置返回結果類型,工作中經常使用到它們。那麼在日常開發中,應該如何正確的選擇呢?下面我們對這兩個屬性分別進行講解和演示。

結果類型resultType

€€€€resultType直譯就是結果的類型,可以設置為期望從select 語句中返回結果的類的全限定名別名。resultType使用場景如下︰

€€€€如果查詢結果只是返回一個值,比如返回String、map或int,那麼可以使用resultType指定簡單類型作為輸出結果。

€€€€我們先了解一個resultType的簡單映射語句示例,它沒有顯式地指定 resultMap。比如︰

<sql id="resultTypeColumn">    id, username, hashedPassword</sql><select id="selectUsers" resultType="map">  select           <include refid="resultTypeColumn"/>  from some_table  where id = #{id}</select>
€€€€上述語句只是簡單地將所有的列映射到 HashMap 的鍵上,這由 resultType 屬性指定。此處對查詢字段用了一個 sql 標簽進行封裝,該sql 片段可復用。

€€€€還有一種情況就是如果數據庫表的字段名和實體bean對象的屬性名一樣。 雖然在大部分情況下都夠用,但是 HashMap 並不是一個很好的領域模型;你的程序更可能會使用 JavaBean 或 POJO(普通老式 Java 對象)作為領域模型,MyBatis 對兩者都提供了支持。看看下面這個 JavaBean︰

package com.someapp.model;public class User {  private int id;  private String username;  private String hashedPassword; // omit getter,setter and toString}
€€€€基于 JavaBean 的規範,上面這個類有 3 個屬性︰id,username 和 hashedPassword,它們會對應到 select 語句中的列名。這樣的一個 JavaBean 可以被映射到 ResultSet,就像映射到 HashMap 一樣簡單。

<select id="selectUsers" resultType="com.someapp.model.User">  select   <include refid="resultTypeColumn"/>  from some_table  where id = #{id}</select>
€€€€類型別名是你的好幫手,關于如何設置類型別名,請移步《Spring Boot MyBatis使用type-aliases-package自定義類別名》。使用別名後就可以不用輸入類的全限定名了。譬如︰

<select id="selectUsers" resultType="User">  select   <include refid="resultTypeColumn"/>  from some_table  where id = #{id}</select>
€€€€在此情況下,MyBatis 會在幕後自動創建一個 resultMap,再根據屬性名來映射列到 JavaBean 的屬性上。如果列名和屬性名不能匹配上,可以在 SELECT 語句中設置列別名(這是一個基本的 SQL 特性)來完成匹配。例如︰

<sql id="resultTypeColumn">    user_id             as "id",    user_name           as "userName",    hashed_password     as "hashedPassword"</sql><select id="selectUsers" resultType="map">  select           <include refid="resultTypeColumn"/>  from some_table  where id = #{id}</select>
€€€€注意,如果返回的是集合,那應該設置為集合包含的類型,而不是集合本身的類型。

結果映射resultMap

€€€€resultMap 直譯就是結果映射,該元素是 MyBatis 中最重要最強大的元素。與 resultType 相比,resultMap就要強大許多,它不僅能夠用于簡單查詢,還能用于級聯查詢以及設置緩存,功能可謂是十分的強大。它可以讓你從 90% 的 JDBC ResultSets 數據提取代碼中解放出來,並在一些情形下允許你進行一些 JDBC 不支持的操作。實際上,在為一些比如連接的復雜語句編寫映射代碼的時候,一份 resultMap 能夠代替實現同等功能的數千行代碼。ResultMap 的設計思想是,對簡單的語句做到零配置,對于復雜一點的語句,只需要描述語句之間的關系就行了。溫馨提示︰resultType 和 resultMap 之間只能同時使用一個。

resultMap標簽屬性

€€€€resultMap 標簽的屬性值包括兩個︰

id 屬性︰唯一標識,此 id 值用于 select 標簽 resultMap 屬性的引用。

type 屬性︰表示該 resultMap 的映射結果類型,可以為類的全限定名或者別名。

€€€€resultMap子標簽包括如下幾個 ︰

子標簽
功能
備注
id
指定查詢列中的唯一標識,如果有多個列組成唯一標識,配置多個id
可以不用
result
用于標識一些簡單屬性,包括column和property兩個屬性
常用
association
在主表的pojo中嵌套另一個表的pojo
不推薦使用
collection
把查詢到的多條記錄映射到集合對象
不推薦使用

€€€€result標簽的屬性包括兩個︰


  • column︰數據庫字段名或別名。
  • property︰實體類中的屬性,和column屬性一一對應。
resultMap使用示例

€€€€下面使用一個簡單的例子,來介紹 resultMap 的使用方法。雖然上一節中的例子不用顯式配置 resultMap,但為了講解,我們來看看如果顯式使用外部的 resultMap 會怎樣;這也是解決列名和bean名不匹配的另外一種方式。定義一個resultMap︰

<resultMap id="userResultMap" type="User">  <id property="id" column="user_id" />  <result property="username" column="user_name"/>  <result property="password" column="hashed_password"/></resultMap>
€€€€然後在引用它的語句中設置 resultMap 屬性就行了(注意我們去掉了 resultType 屬性)。比如:

<select id="selectUsers" resultMap="userResultMap">  select user_id, user_name, hashed_password  from some_table  where id = #{id}</select>resultType和resultMap的區別

€€€€下面了解一下MyBatis中數據轉換機制︰在進行查詢映射的時候,其實查詢出來的每一個屬性都是放在一個對應的Map里面,其中鍵是屬性名,值則是其對應的值。當提供的返回類型屬性是resultType的時候,MyBatis會將Map里面的鍵值對取出賦給resultType所指定的對象對應的屬性。所以,其實MyBatis的每一個查詢映射的返回類型都是ResultMap,只是當我們提供的返回類型屬性是resultType的時候,MyBatis自動的把對應的值賦給resultType所指定對象的屬性,而當提供的返回類型是resultMap的時候,因為Map不能很好表示領域模型,我們就需要自己把它轉化為對應的對象,這常常在復雜查詢中很有作用。

€€€€言歸正傳,resultType和resultMap到底有什麼區別呢?

€€€€resultType不需要配置,但是resultMap要配置一下。resultType是直接指定返回類型的,而使用resultMap時,需要在外部ResultMap標簽中,設置數據庫表的字段名和實體bean對象類的屬性的一一對應關系。設置後,就算數據庫的字段名和實體類的屬性名不一樣也沒有關系,mybatis依然會給映射出來,所以resultMap要更強大一些。

€€€€就像上面說的那樣,如果查詢出來數據庫字段名(包括字段別名)和要封裝的實體bean對象屬性值不相同時,只能使用resultMap來返回結果。

€€€€還有一個區別是resultMap可以用在復雜聯合查詢上,而resultType不可以。關于這一點,大家可以去Mybatis官網了解一下,這里點到為止。

結束語

€€€€至此,大家已經了解了resultType和resultMap的基本用法,在日常業務開發中已經可以游刃有余了。如果想更上一層樓,掌握更多關于resultMap的高級用法,請移步Mybatis官網。

€€€€當你遇到這個話題的時候,你通常怎麼理解呢?你踫到過特別精彩、讓人印象深刻的回答嗎?歡迎大家積極留言交流。

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|小黑屋|黑莲技术资源论坛 ( 闽ICP备18016623号-7 )|网站地图

GMT+8, 2022-10-7 20:41 , Processed in 0.434306 second(s), 25 queries .

Powered by BBS.HL1.NET X3.4 © 2020-2022

本站IT社区(bbs.hl1.net)所有的资源教程均来自网友分享及互联网收集

快速回复 返回顶部 返回列表