最近在使用mybatis查詢數據庫時,發現在pl/sql中單獨執行sql時結果是有值的,但是在程序中拿到的卻是null,相關配置如下:
(1)
<resultMap type="monitorTaskStatus" id="monitorTaskStatusMap">
<result column="BATCH_NUM" property="batchNum"/>
<result column="TASK_STATUS" property="taskStatus"/>
<result column="CALLED_PHONENUM" property="calledPhoneNum"/>
</resultMap>
(2)
<select id="queryStatusByProjectId" parameterType="java.lang.String" resultType="monitorTaskStatusMap">
select b.batch_num, c.called_phonenum,c.task_status
from cc_call_task c
left join cc_batch_calledperson b
on c.batch_id = b.batch_id
where b.batch_type in (2, 3)
and c.task_status != 5
<if test="value != null and value != ''">
and c.project_id = #{value}
</if>
</select>
(3)
java:
List<TaskStatus> callTasks = service.queryStatusByProjectId(projectId);
debug時發現callTasks.size()=1,但是值卻是null,最后搞了半天才發現原來(1)中<select>標簽的resultType屬性使用錯誤,改成resultMap即可
究其原因是,MyBatis中在查詢進行select映射的時候,返回類型可以用resultType,也可以用resultMap,resultType是直接表示返回類型的,而resultMap則是對外部resultMap標簽的引用(如本例中的(1)),但是resultType跟resultMap不能同時存在。在MyBatis進行查詢映射的時候,其實查詢出來的每一個屬性都是放在一個對應的Map里面的,其中鍵是屬性名,值則是其對應的值。當提供的返回類型屬性是resultType的時候,MyBatis會將Map里面的鍵值對取出賦給resultType所指定的對象對應的屬性。所以其實MyBatis的每一個查詢映射的返回類型都是ResultMap,只是當我們提供的返回類型屬性是resultType的時候,MyBatis對自動的給我們把對應的值賦給resultType所指定對象的屬性,而當我們提供的返回類型是resultMap的時候,因為Map不能很好表示領域模型,我們就需要自己再進一步的把它轉化為對應的對象,這常常在復雜查詢中很有作用。(包括如本例中的表關聯查詢等等情況)
終上所述,本例中錯誤的原因在於已經自定義了<resultMap>中id為monitorTaskStatusMap的結果集,而需求也是要引用這個,正確的是應該用resultMap指定,我卻用了resultType。。。
最后可以簡要概括兩點:
1.當進行單表簡單查詢時且返回值類型是基本類型時,一般盡量使用resultType;
2.當進行表關聯查詢時,或者說xml中定義了相關的resultMap標簽,那么就一般盡量使用resultMap;
3.resultType和resultMap不能同時使用。