ResultMap
基本使用
適合使用返回值是自定義實體類的情況
映射實體類的數據類型
id:resultMap的唯一標識
column: 庫表的字段名
property: 實體類里的屬性名
resultType可以直接返回給出的返回值類型,比如String、int、Map,等等,其中返回List也是將返回類型定義為Map,然后mybatis會自動將這些map放在一個List中,resultType還可以是一個對象
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- namespace:當前庫表映射文件的命名空間,唯一的不能重復 -->
<mapper namespace="com.hao947.sql.mapper.PersonMapper">
<!-- type:映射實體類的數據類型 id:resultMap的唯一標識 -->
<resultMap type="person" id="BaseResultMap">
<!-- column:庫表的字段名 property:實體類里的屬性名 -->
<id column="person_id" property="personId" />
<result column="name" property="name" />
<result column="gender" property="gender" />
<result column="person_addr" property="personAddr" />
<result column="birthday" property="birthday" />
</resultMap>
<!--id:當前sql的唯一標識
parameterType:輸入參數的數據類型
resultType:返回值的數據類型
#{}:用來接受參數的,如果是傳遞一個參數#{id}內容任意,如果是多個參數就有一定的規則,采用的是預編譯的形式select
* from person p where p.id = ? ,安全性很高 -->
<!-- sql語句返回值類型使用resultMap -->
<select id="selectPersonById" parameterType="java.lang.Integer"
resultMap="BaseResultMap">
select * from person p where p.person_id = #{id}
</select>
<!-- resultMap:適合使用返回值是自定義實體類的情況
resultType:適合使用返回值的數據類型是非自定義的,即jdk的提供的類型 -->
<select id="selectPersonCount" resultType="java.lang.Integer">
select count(*) from
person
</select>
<select id="selectPersonByIdWithMap" parameterType="java.lang.Integer"
resultType="java.util.Map">
select * from person p where p.person_id= #{id}
</select>
</mapper>
resultType是結果集的一個映射,可以簡單的寫成resultType="map"或者resultType="hashmap",其中"map"和"hashmap"都是mybatis能夠識別的別名,寫成"java.util.HashMap"當然也沒有問題,在java代碼端,是這么寫的:
List<Map<String,Object>> list =sqlSession.selectList("User.test");
for(Map<String,Object> map :list){
System.out.println(map.get("id")); //通過map.get("key"),就可以獲取你需要的結果。
}
****************************************MyBatis如何寫條件查詢**************************************************
基本標簽語句
<select id="" parameterType="" resultMap="xxResultMap">
sql語句
</select>
id標識該查詢;parameterType指參數類型;resultMap指返回類型,這里與下面設置的resultMap關聯。
作為查詢語句,返回結果是一個List,當選擇性的輸出字段時,需要添加一個ResultMap屬性與之關聯。id標識主鍵,result標識字段。property指向實體類的屬性,column指向數據庫列名。
拼接條件之前需要加where關鍵字。
因為可能沒有查詢條件,所以寫成where 1=1。或者用查詢的必要條件拼接。
拼接條件為“=”的情況
用 if 判斷是否為空,不為空則用AND拼接。變量寫成#{xx}
拼接條件為"LIKE"模糊查詢,適用於MySql數據庫
if 條件一樣,另外要用concat作拼接。
like concat('%', #{userName}, '%')
oracle數據庫中,模糊查詢報錯“參數缺失”。
模糊查詢的格式問題
法一:用"||"分隔。like '%' || #{userName} || '%'
法二:like concat(concat('%', #{userName}), '%')
Mybatis中實現傳統多條件查詢
數據表student如下:
已有的數據如下:
我們現在進行如下查詢:
查詢表中grade>70 age>20 的女生
SQL語句自然如下:
select * from student where sex="女" and grade>70 and age>20;
在數據庫中直接執行這句SQL語句:

現在使用Mybatis完成這個操作:
在student.xml中添加如下配置語句:

測試語句:
因為傳入的參數有多個 所以需要使用Map來傳遞
可以得到剛才的答案
這樣的查詢引出了下面三個問題:
1.無法靈活的添加條件
2.如果只想按照年齡與成績查詢 不能在sex處賦值為空 仍需要新的SQL語句
3.如果采用拼接的方式(其實這樣也算改變了SQL語句)非常容易產生格式錯誤或者順序錯誤
動態SQL:if
應用場景1:
假設我們現在需要對student表進行兩種操作:
- 查詢所有信息
- 根據專業名進行模糊查詢
按照現在的方式 我們必須提供2條SQL語句分別應對這兩種操作
此時我們介紹一下動態SQL中的if標簽在這里的使用:
我們來解釋一下這條SQL語句:
這條語句意味着:如果沒有傳入參數major 那么執行select * from student 即查詢所有
如果傳入了參數majo 那么執行這句模糊查詢
注意:這里的<if test>中的test僅為語法 實際等於if()
測試一下這兩種情況:
第二種情況:
應用場景2:
現在需要進行這種查詢:
根據姓名與專業來查詢數據:如果姓名為空 將只根據專業來查詢 如果姓名不為空 將只根據姓名來查詢
傳統SQL語句如下:
select * from student where name=#{name} and major=#{major};
在上面的SQL語句中我們發現 如果#{name}為空 那么查詢結果直接為空 並不能進入“根據專業查詢”這一個環節
我們在測試中發現 根據name來查詢可以得到正確結果 而name為空 試圖根據major來查詢時報錯
這是因為當major為空 name不為空時 SQL語句如下:
我們發現問題出在這個where上
如何解決這個問題呢?
<where>標簽可以自動進行判斷
如果任何條件都不成立 那么在SQL語句中不會出現where
如果有條件成立 且這個標簽返回的內容是以“AND”或“OR”開頭的 會自動去掉這個多出來的and或者or
在測試代碼中:
<!-- 導出所有數據 -->
<select id="exportAll" resultMap="map">
SELECT t1.MEDICAL_ID AS medicalId,
ADDRESS AS address,
DATE_START AS dateStart,
DATE_END AS dateEnd,
TIME_START AS timeStart,
TIME_END AS timeEnd,
AMBULANCE_NUM AS ambulanceNum,
NAME AS name,
PHONE AS phone
FROM PM.T_MEETING_MEDICAL t1,PM.T_MEETING_MEDICAL_DOCTOR t2
<where> t1.MEDICAL_ID = t2.MEDICAL_ID <if test="address != null and address !='' "> AND ADDRESS = #{address} </if> <if test="dateStart != null and dateStart !='' "> AND DATE_START = #{dateStart} </if> <if test="dateEnd != null and dateEnd !='' "> AND DATE_END = #{dateEnd} </if> <if test="meetingId != null and meetingId !='' "> AND MEETING_ID = #{meetingId} </if> </where> ORDER BY t1.ADDRESS,t1.DATE_START </select>
public List<Map<String, Object>> exportAll(MeetingMedicalVo meetingMedicalVo);//接口
resultType*****************************************************************************************************************************
resultType是結果集的一個映射,可以簡單的寫成resultType="map"或者resultType="hashmap",其中"map"和"hashmap"都是mybatis能夠識別的別名,寫成"java.util.HashMap"當然也沒有問題。
說白了,即便使用resultType,mybatis也將使用resultMap進行查詢結果的映射。只是映射過程我們是看不見的,方便寫代碼。
resultMap中id和result的區別:這兩者之間的唯一不同是id 表示的結果將是當比較對象實例時用到的標識屬性。這幫助來改進整體表現,特別是緩存和嵌入結果映射(也就是聯合映射) 。官方原話,簡單的理解,就是當某一個列是唯一索引時,用id標簽,提高效率。
MyBatis擁有自動封 裝功能,只要你提供了返回類型,MyBatis會根據自己的判斷來利用查詢結果封裝對應的對象,所以前面的簡單查詢中,如果你不在resultMap中明 確的指出id對應哪個字段,title對應哪個字段,MyBatis也會根據自身的判斷來幫你封裝,MyBatis的自身判斷是把查詢的field或其對 應的別名與返回對象的屬性進行比較,如果相匹配且類型也相匹配,MyBatis則會對其進行賦值。