解決mybatis查詢Map接收值為null不存key的問題
今天跟大家討論下mybatis查詢Map接收值為null不存key的問題
問題出現的前提條件:將資料從DB中查詢出來時將查出來的欄位對映為Map,而不是封裝成Bean.
我們看下mybatis查詢使用map接收時遇到的問題:
xml檔案:
SELECT a.apply_id AS "applyId", a.ali_pid AS "aliPid", a.ali_account AS "aliAccount", a.agreement_resource_ids AS "agreementResourceIds", a.status AS "status", a.error_field AS "errorField", ac.company_name AS "companyName", u.name AS "userName", DATE_FORMAT(a.create_date,'%Y-%m-%d') AS "createDate", sa1.name AS "provinceName", sa2.name AS "cityName", sa3.name AS "regionName", ac.address AS "address", acbac.status AS "aliStatus", acbl.reason_desc AS "reasonDesc", aac.memo AS "memo"
返回結果:
applyId=174, address=測試, cityName=北京市, aliPid=2088123123123213, aliAccount=123123123123, companyName=企業20181212, regionName=東城區, provinceName=北京, userName=張三, aliStatus=3, status=2, createDate=2018-12-28
根據返回結果看到,並沒有memo欄位,原因是該欄位在DB中的值為null,所以說map接收資料庫中為null的值不會存在對應的鍵值。
出現這種情況的原因:
maibatis在預設情況下,對Map的解析生成如果value為null的話,那麼key不會被加入到map中,所以map接收結果時就沒有value為null的鍵值。
解決方法:在mybatis配置檔案中設定callSettersOnNulls設定為true,該屬性預設為false。
callSetterOnNulls:指定當結果集中值為 null 的時候是否呼叫對映物件的 setter(map 物件時為 put)方法,這對於有 Map.keySet() 依賴或 null 值初始化的時候是有用的。注意基本型別(int、boolean等)是不能設定成 null 的。
<!-- 全域性引數 --> <settings> <!-- 設定當結果集中為null,呼叫setter(map 為put)方法 --> <setting name="callSettersOnNull" value="true"/> </settings>
加上該配置的返回結果:
memo=null, address=測試, aliPid=2088123123123213, companyName=測試企業20181212, regionName=東城區, userName=張三, applyId=174, errorField=null, cityName=北京市, aliAccount=123123123123, provinceName=北京, agreementResourceIds=null, aliStatus=3, reasonDesc=null, status=2, createDate=2018-12-28
在應用層查詢的map已經有這個鍵值了,解決了結果集為null但是沒用存鍵值的問題。
在解決該問題過程中,看到網上有說如果只查詢一個欄位,並且結果為null用map接收時,結果為空map。
就此我進行了測試:
xml檔案:
SELECT a.memo AS "memo" from a
結果:
{memo=null}
經此實驗這種說法是不正確的,接收到一個所有key值都為null 的map 而不是一個為null的map;
但是我帶到頁面上的結果還是沒有memo這個欄位,(一直以為是這個配置沒有起作用,只顧著看前端接收到的返回值,沒有關注後端的結果。自己要蠢死了)
最後找到了問題,因為我應用層使用了Gson序列化
return GsonUtil.getGson().toJson(map);
Gson預設當屬性的值設為空時不會被序列化,如果強制序列化null值,我們可以使用GsonBuilder來序列化提供null值;
new GsonBuilder().serializeNulls().create().toJson(result);可以將null值也序列化。
前端頁面接收返回結果:
如果跟大家理解有出入,歡迎提出一起討論。。。。。