天天看點

resultMap與resultType、parameterMap與 parameterType的差別

Map:映射;Type:Java類型

resultMap 與 resultType、parameterMap 與  parameterType的差別在面試的時候被問到的幾率非常高,出現的次數到了令人發指的地步,筆者認為有必要單獨列一章鄭重聲明,共勉
           

resultMap & resultType

兩者都是表示查詢結果集與java對象之間的一種關系,處理查詢結果集,映射到java對象。

resultMap 是一種“查詢結果集---Bean對象”屬性名稱映射關系,使用resultMap關系可将将查詢結果集中的列一一映射到bean對象的各個屬性(兩者屬性名可以不同,配置好映射關系即可),适用與複雜一點的查詢。

 (1)适用于表的連接配接查詢(在resultMap裡面可以配置連接配接條件,見如下程式association标簽)
           
<!-- 訂單查詢關聯使用者的resultMap将整個查詢的結果映射到cn.itcast.mybatis.po.Orders中   -->  
    <resultMap type="cn.itcast.mybatis.po.Orders" id="OrdersUserResultMap">  
        <!-- 配置映射的訂單資訊 -->  
        <!-- id:指定查詢列中的唯 一辨別,訂單資訊的中的唯 一辨別,如果有多個列組成唯一辨別,配置多個id ,column:訂單資訊的唯 一辨別列 ,property:訂單資訊的唯 一辨別 列所映射到Orders中哪個屬性  -->  
 
        <id column="id" property="id"/>
        <result column="user_id" property="userId"/> 
        <result column="number" property="number"/> 
        <result column="createtime" property="createtime"/>
        <result column="note" property=note/>          
 
        <!-- 配置映射的關聯的使用者資訊 --> 
        <!-- association:用于映射關聯查詢單個對象的資訊property:要将關聯查詢的使用者資訊映射到Orders中哪個屬性 -->  
 
        <association property="user"  javaType="cn.itcast.mybatis.po.User">
            <!-- id:關聯查詢使用者的唯 一辨別
            column:指定唯 一辨別使用者資訊的列
            javaType:映射到user的哪個屬性-->
            <id column="user_id" property="id"/>
            <result column="username" property="username"/>
            <result column="sex" property="sex"/>
            <result column="address" property="address"/>
        </association> 
    </resultMap>
           

(2)适用于表的一對多連接配接查詢,(如,訂單對應多個訂單明細時,需要根據連接配接條件訂單id比對訂單明細,并且消除重複的訂單資訊(訂單明細中的),如下程式);

<resultMap type="cn.itcast.mybatis.po.Orders" 		id="OrdersAndOrderDetailResultMap" extends="OrdersUserResultMap">
        <!-- 訂單資訊 --> 
        <!-- 使用者資訊 -->
        <!-- 使用extends繼承,不用在中配置訂單資訊和使用者資訊的映射 -->
        <!-- 訂單明細資訊一個訂單關聯查詢出了多條明細,要使用collection進行映射
        collection:對關聯查詢到多條記錄映射到集合對象中
        property:将關聯查詢到多條記錄映射到cn.itcast.mybatis.po.Orders哪個屬性 
        ofType:指定映射到list集合屬性中pojo的類型 -->  
 
         <collection property="orderdetails" ofType="cn.itcast.mybatis.po.Orderdetail">
            <!-- id:訂單明細唯 一辨別 
            property:要将訂單明細的唯 一辨別 映射到cn.itcast.mybatis.po.Orderdetail的哪個屬性-->  
            <id column="orderdetail_id" property="id"/>
            <result column="items_id" property="itemsId"/>
            <result column="items_num" property="itemsNum"/>
            <result column="orders_id" property="ordersId"/>
         </collection>
    </resultMap> 
           

(3)映射的查詢結果集中的列标簽可以根據需要靈活變化,并且,在映射關系中,還可以通過typeHandler設定實作查詢結果值的類型轉換,比如布爾型與0/1的類型轉換。

例如:

<resultMaptype="hdu.terence.bean.Message" id="MessageResult"> 
    <!--存放Dao值--><!--type是和資料庫對應的bean類名Message-->
    <id column="id" jdbcType="INTEGER"property=" id"/><!--主鍵标簽-->
    <result column="COMMAND" jdbcType="VARCHAR" property="command"/>
    <result column="DESCRIPTION" jdbcType="VARCHAR" property="description"/>
    <result column="CONTENT" jdbcType="VARCHAR" property="content"/>
  </resultMap> 
 
  <select id="queryMessageList" parameterType="hdu.terence.bean.Message" resultMap="MessageResult">
    SELECTID,COMMAND,DESCRIPTION,CONTENT FROM message WHERE 1=1    
    <if test="command!=null and!&quot;&quot;.equals(command.trim())">
    and COMMAND=#{command}
    </if>
    <if test="description!=null and!&quot;&quot;.equals(description.trim())">
    and DESCRIPTION like '%' #{description} '%'
    </if> 
  </select>
           
resultType 是一種“查詢結果集---Bean對象”資料類型映射關系,使用resultType關系,即可使Bean對象接收查詢結果集;見名知意,該方法是通過查詢結果集中每條記錄(屬性)的資料類型和Bean對象的資料類型作映射,若兩者都相同,則表示比對成功,Bean可以接收到查詢結果。

    但是剛方法有局限性,要求Bean對象字段名和查詢結果集的屬性名相同(可以大小寫不同,大小寫不敏感)。因為這個局限性,可以省略調resultMap進行屬性名映射。

   一般适用于pojo(簡單對象)類型資料,簡單的單表查詢。

   以下是resultType的寫法,将其值設定成對應的java類上即可。不需要上述resultMap的映射關系。
           
<select id="queryMessageList" parameterType="hdu.terence.bean.Message"   resultType=" hdu.terence.bean.Message ">
    SELECTID,COMMAND,DESCRIPTION,CONTENT FROM message WHERE 1=1     
    <if test="command!=null and!&quot;&quot;.equals(command.trim())">
    and COMMAND=#{command}
    </if>
    <if test="description!=null and!&quot;&quot;.equals(description.trim())">
    and DESCRIPTION like '%' #{description} '%'
    </if> 
  </select>
           

ParameterMap(不推薦) & parameterType

ParameterMap和resultMap類似,表示将查詢結果集中列值的類型一一映射到java對象屬性的類型上,在開發過程中不推薦這種方式。

一般使用parameterType直接将查詢結果列值類型自動對應到java對象屬性類型上,不再配置映射關系一一對應,例如上述代碼中下劃線部分表示将查詢結果類型自動對應到hdu.terence.bean.Message的Bean對象屬性類型。     
           

Mybatis家族曆史

Mybatis出生于GoogleCode,使用的這兩個名字叫做resultType和parameterType。

以前的版本叫做iBatis,出生于Apache,以前這兩個配置叫做resultClass和parrameterClass,根據這種命名也應該知道這種映射都和java類有關。 
           

#{}和KaTeX parse error: Expected 'EOF', got '#' at position 36: …meterMap書寫拼寫要使用#̲{},resultType 和…{},使用例子如下:

Select ID,COMMAND from Message where COMMAND=#{command}

Select ID,COMMAND from Message where COMMAND=‘${command}’

前者解析為:

Select ID,COMMAND from Message where COMMAND=?具有預編譯效果
           

後者解析為:

Select ID,COMMAND from Message where COMMAND=段子   不具有預編譯效果
           

但是,例如當頁面向背景傳遞一個列名(屬性名)的時候,是不希望被預編譯出一個?的,此時要用到$格式;

如:加上 order by${param} ,此時param是一個列名。

#{}和 ognl表達式

一般參數的拼寫還是保證統一風格為好,便于人讀。

Map:映射;Type:Java類型

resultMap 與 resultType、parameterMap 與 parameterType的差別在面試的時候被問到的幾率非常高,項目中出現了一個小bug,是以來共同回顧下幾個東西:

resultMap表示将查詢結果集中的列一一映射到bean對象的各個屬性。映射的查詢結果集中的列标簽可以根據需要靈活變化,并且,在映射關系中,還可以通過typeHandler設定實作查詢結果值的類型轉換,比如布爾型與0/1的類型轉換。

resultType 表示的是bean中的對象類,此時可以省略掉resultMap标簽的映射,但是必須保證查詢結果集中的屬性 和 bean對象類中的屬性是一一對應的,此時大小寫不敏感,但是有限制。

推薦使用resultMap而非resultType。

ParameterMap和resultMap類似,表示将查詢結果集中列值的類型一一映射到java對象屬性的類型上,在開發過程中不推薦這種方式。

一般使用parameterType直接将查詢結果列值類型自動對應到java對象屬性類型上,不再配置映射關系一一對應,例如上述代碼中下劃線部分表示将查詢結果類型自動對應到hdu.terence.bean.Message的Bean對象屬性類型。
           

推薦使用parameterType而非parameterMap。

關于面試中還有一個經常問的就是${}與#{}的差別:

使用#傳入參數是,sql語句解析是會加上"",比如 select * from table where name = #{name} ,傳入的name為小李,那麼最後列印出來的就是

select * from table where name = ‘小李’,就是會當成字元串來解析,這樣相比于KaTeX parse error: Expected 'EOF', got '#' at position 13: 的好處是比較明顯對的吧,#̲{}傳參能防止sql注入,如果…{},這種方式 那麼是會報錯的,

目前來看,能用#就不要用$,

mybatis中的#和$的差別

  1. #将傳入的資料都當成一個字元串,會對自動傳入的資料加一個雙引号。如:order by #user_id#,如果傳入的值是111,那麼解析成sql時的值為order by “111”, 如果傳入的值是id,則解析成的sql為order by “id”.
  2. $将傳入的資料直接顯示生成在sql中。如:order by u s e r i d user_id useri​d,如果傳入的值是111,那麼解析成sql時的值為order by user_id, 如果傳入的值是id,則解析成的sql為order by id.
  3. #方式能夠很大程度防止sql注入。

4.$方式無法防止Sql注入。

5.$方式一般用于傳入資料庫對象,例如傳入表名.

6.一般能用#的就别用$.

MyBatis排序時使用order by 動态參數時需要注意,用$而不是#

字元串替換

預設情況下,使用#{}格式的文法會導緻MyBatis建立預處理語句屬性并以它為背景設定安全的值(比如?)。這樣做很安全,很迅速也是首選做法,有時你隻是想直接在SQL語句中插入一個不改變的字元串。比如,像ORDER BY,你可以這樣來使用:

ORDER BY ${columnName}

這裡MyBatis不會修改或轉義字元串。

重要:接受從使用者輸出的内容并提供給語句中不變的字元串,這樣做是不安全的。這會導緻潛在的SQL注入攻擊,是以你不應該允許使用者輸入這些字段,或者通常自行轉義并檢查。

————————————————

版權聲明:本文為CSDN部落客「Terence Jing」的原創文章,遵循CC 4.0 BY-SA版權協定,轉載請附上原文出處連結及本聲明。

原文連結:https://blog.csdn.net/CSDN_Terence/article/details/60779889

https://blog.csdn.net/weixin_34006965/article/details/86254383