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!"".equals(command.trim())">
and COMMAND=#{command}
</if>
<if test="description!=null and!"".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!"".equals(command.trim())">
and COMMAND=#{command}
</if>
<if test="description!=null and!"".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中的#和$的差別
- #将傳入的資料都當成一個字元串,會對自動傳入的資料加一個雙引号。如:order by #user_id#,如果傳入的值是111,那麼解析成sql時的值為order by “111”, 如果傳入的值是id,則解析成的sql為order by “id”.
- $将傳入的資料直接顯示生成在sql中。如:order by u s e r i d user_id userid,如果傳入的值是111,那麼解析成sql時的值為order by user_id, 如果傳入的值是id,則解析成的sql為order by id.
- #方式能夠很大程度防止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