MyBatis標(biāo)簽之Select?resultType和resultMap詳解
摘要:介紹MyBatis 中Select標(biāo)簽的兩個屬性resultType和resultMap及其區(qū)別。
MyBatis常用動態(tài)標(biāo)簽大全見上述URL,它們大概分為如下四類:
標(biāo)簽 | 作用 | 使用場景 |
---|---|---|
foreach | 循環(huán)語句 | 批量添加或者批量查詢 |
if | 條件判斷語句 | 單條件分支判斷 |
choose、when、otherwise | 類似 Java 中的 switch、case、default 語句 | 多條件分支判斷 |
trim、where、set | 輔助標(biāo)簽 | 用于處理一些條件查詢 |
在MyBatis中有一個ResultMap標(biāo)簽,它是為了映射select標(biāo)簽查詢出來的結(jié)果集,其主要作用是將實體類中的字段與數(shù)據(jù)庫表中的字段進(jìn)行關(guān)聯(lián)映射。
前言
Mybatis 中 select 標(biāo)簽有兩個屬性 resultType 和 resultMap,用于在mapper.xml文件中配置返回結(jié)果類型,工作中經(jīng)常使用到它們。那么在日常開發(fā)中,應(yīng)該如何正確的選擇呢?下面我們對這兩個屬性分別進(jìn)行講解和演示。
結(jié)果類型resultType
resultType直譯就是結(jié)果的類型,可以設(shè)置為期望從select 語句中返回結(jié)果的類的全限定名或別名。resultType使用場景如下:
如果查詢結(jié)果只是返回一個值,比如返回String、map或int,那么可以使用resultType指定簡單類型作為輸出結(jié)果。
我們先了解一個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 標(biāo)簽進(jìn)行封裝,該sql 片段可復(fù)用。
還有一種情況就是如果數(shù)據(jù)庫表的字段名和實體bean對象的屬性名一樣。 雖然在大部分情況下都夠用,但是 HashMap 并不是一個很好的領(lǐng)域模型;你的程序更可能會使用 JavaBean 或 POJO(普通老式 Java 對象)作為領(lǐng)域模型,MyBatis 對兩者都提供了支持。看看下面這個 JavaBean:
package com.someapp.model; public class User { private int id; private String username; private String hashedPassword; // omit getter,setter and toString }
基于 JavaBean 的規(guī)范,上面這個類有 3 個屬性:id,username 和 hashedPassword,它們會對應(yīng)到 select 語句中的列名。這樣的一個 JavaBean 可以被映射到 ResultSet
,就像映射到 HashMap
一樣簡單。
<select id="selectUsers" resultType="com.someapp.model.User"> select <include refid="resultTypeColumn"/> from some_table where id = #{id} </select>
類型別名是你的好幫手,關(guān)于如何設(shè)置類型別名,請移步《Spring Boot MyBatis使用type-aliases-package自定義類別名》。使用別名后就可以不用輸入類的全限定名了。譬如:
<select id="selectUsers" resultType="User"> select <include refid="resultTypeColumn"/> from some_table where id = #{id} </select>
在此情況下,MyBatis 會在幕后自動創(chuàng)建一個 resultMap
,再根據(jù)屬性名來映射列到 JavaBean 的屬性上。如果列名和屬性名不能匹配上,可以在 SELECT 語句中設(shè)置列別名(這是一個基本的 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>
注意,如果返回的是集合,那應(yīng)該設(shè)置為集合包含的類型,而不是集合本身的類型。
結(jié)果映射resultMap
resultMap
直譯就是結(jié)果映射,該元素是 MyBatis 中最重要最強大的元素。與 resultType 相比,resultMap就要強大許多,它不僅能夠用于簡單查詢,還能用于級聯(lián)查詢以及設(shè)置緩存,功能可謂是十分的強大。它可以讓你從 90% 的 JDBC ResultSets
數(shù)據(jù)提取代碼中解放出來,并在一些情形下允許你進(jìn)行一些 JDBC 不支持的操作。實際上,在為一些比如連接的復(fù)雜語句編寫映射代碼的時候,一份 resultMap
能夠代替實現(xiàn)同等功能的數(shù)千行代碼。ResultMap 的設(shè)計思想是,對簡單的語句做到零配置,對于復(fù)雜一點的語句,只需要描述語句之間的關(guān)系就行了。溫馨提示:resultType 和 resultMap 之間只能同時使用一個。
resultMap標(biāo)簽屬性
resultMap 標(biāo)簽的屬性值包括兩個:
- id 屬性:唯一標(biāo)識,此 id 值用于 select 標(biāo)簽 resultMap 屬性的引用。
- type 屬性:表示該 resultMap 的映射結(jié)果類型,可以為類的全限定名或者別名。
resultMap子標(biāo)簽包括如下幾個 :
子標(biāo)簽 | 功能 | 備注 |
---|---|---|
id | 指定查詢列中的唯一標(biāo)識,如果有多個列組成唯一標(biāo)識,配置多個id | 可以不用 |
result | 用于標(biāo)識一些簡單屬性,包括column和property兩個屬性 | 常用 |
association | 在主表的pojo中嵌套另一個表的pojo | 不推薦使用 |
collection | 把查詢到的多條記錄映射到集合對象 | 不推薦使用 |
result標(biāo)簽的屬性包括兩個:
- column:數(shù)據(jù)庫字段名或別名。
- property:實體類中的屬性,和column屬性一一對應(yīng)。
resultMap使用示例
下面使用一個簡單的例子,來介紹 resultMap 的使用方法。雖然上一節(jié)中的例子不用顯式配置 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>
然后在引用它的語句中設(shè)置 resultMap
屬性就行了(注意我們?nèi)サ袅?resultType
屬性)。比如:
<select id="selectUsers" resultMap="userResultMap"> select user_id, user_name, hashed_password from some_table where id = #{id} </select>
resultType和resultMap的區(qū)別
下面了解一下MyBatis中數(shù)據(jù)轉(zhuǎn)換機制:在進(jìn)行查詢映射的時候,其實查詢出來的每一個屬性都是放在一個對應(yīng)的Map里面,其中鍵是屬性名,值則是其對應(yīng)的值。當(dāng)提供的返回類型屬性是resultType的時候,MyBatis會將Map里面的鍵值對取出賦給resultType所指定的對象對應(yīng)的屬性。所以,其實MyBatis的每一個查詢映射的返回類型都是ResultMap,只是當(dāng)我們提供的返回類型屬性是resultType的時候,MyBatis自動的把對應(yīng)的值賦給resultType所指定對象的屬性,而當(dāng)提供的返回類型是resultMap的時候,因為Map不能很好表示領(lǐng)域模型,我們就需要自己把它轉(zhuǎn)化為對應(yīng)的對象,這常常在復(fù)雜查詢中很有作用。
言歸正傳,resultType和resultMap到底有什么區(qū)別呢?
resultType不需要配置,但是resultMap要配置一下。resultType是直接指定返回類型的,而使用resultMap時,需要在外部ResultMap標(biāo)簽中,設(shè)置數(shù)據(jù)庫表的字段名和實體bean對象類的屬性的一一對應(yīng)關(guān)系。設(shè)置后,就算數(shù)據(jù)庫的字段名和實體類的屬性名不一樣也沒有關(guān)系,mybatis依然會給映射出來,所以resultMap要更強大一些。
就像上面說的那樣,如果查詢出來數(shù)據(jù)庫字段名(包括字段別名)和要封裝的實體bean對象屬性值不相同時,只能使用resultMap來返回結(jié)果。
還有一個區(qū)別是resultMap可以用在復(fù)雜聯(lián)合查詢上,而resultType不可以。關(guān)于這一點,大家可以去Mybatis官網(wǎng)了解一下,這里點到為止。
結(jié)束語
至此,大家已經(jīng)了解了resultType和resultMap的基本用法,在日常業(yè)務(wù)開發(fā)中已經(jīng)可以游刃有余了。如果想更上一層樓,掌握更多關(guān)于resultMap的高級用法,請移步Mybatis官網(wǎng)。
當(dāng)你遇到這個話題的時候,你通常怎么理解呢?你碰到過特別精彩、讓人印象深刻的回答嗎?歡迎大家積極留言交流。
Reference
https://mybatis.org/mybatis-3/zh/sqlmap-xml.html
https://baijiahao.baidu.com/s?id=1696473444790362129&wfr=spider&for=pc
到此這篇關(guān)于MyBatis標(biāo)簽之Select resultType和resultMap的文章就介紹到這了,更多相關(guān)MyBatis Select resultType和resultMap內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java/Web調(diào)用Hadoop進(jìn)行MapReduce示例代碼
本篇文章主要介紹了Java/Web調(diào)用Hadoop進(jìn)行MapReduce示例代碼,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-11-11SpringBoot整合JWT框架,解決Token跨域驗證問題
Json web token (JWT), 是為了在網(wǎng)絡(luò)應(yīng)用環(huán)境間傳遞聲明而執(zhí)行的一種基于JSON的開放標(biāo)準(zhǔn)((RFC 7519).定義了一種簡潔的,自包含的方法用于通信雙方之間以JSON對象的形式安全的傳遞信息。2021-06-06Java Math.round(),Math.ceil(),Math.floor()的區(qū)別詳解
這篇文章主要介紹了Java Math.round(),Math.ceil(),Math.floor()的區(qū)別詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-08-08java遞歸實現(xiàn)拼裝多個api的結(jié)果操作方法
本文給大家分享java遞歸實現(xiàn)拼裝多個api的結(jié)果的方法,說白了就是好幾個API結(jié)果拼裝成的,本文通過實例代碼給大家介紹的非常詳細(xì),需要的朋友參考下吧2021-09-09解決SpringBoot的@DeleteMapping注解的方法不被調(diào)用問題
這篇文章主要介紹了解決SpringBoot的@DeleteMapping注解的方法不被調(diào)用問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-01-01