Java?Mybatis使用resultMap時(shí),屬性賦值順序錯(cuò)誤的巨坑
Mybatis使用resultMap屬性賦值順序錯(cuò)誤
今天發(fā)現(xiàn)個(gè)坑,新建的表使用生成工具生成的mapper文件和實(shí)體類后,發(fā)現(xiàn)少了個(gè)字段就又手動(dòng)加了下,結(jié)果發(fā)現(xiàn)一個(gè)問(wèn)題
ids是后加入的字段
@Data
@Builder
public class QueryRecordPo {
?
? ? ?//若干其他屬性....
? ? private String outputField;
? ? ?//后加的
? ? private String ids;
?
? ? //若干其他屬性
? ? //...?
}resultMap中是這樣寫(xiě)的
? ? <resultMap id="BaseResultMap" type="...."> ? ? ? ? <id column="id" jdbcType="BIGINT" property="id"/> ? ? ? ? ..若干其他屬性 ? ? ? ? <result column="ids" jdbcType="VARCHAR" property="ids"/> ? ? ? ? <result column="output_field" jdbcType="VARCHAR" property="outputField"/> ? ? ? ? ..若干其他屬性 ? ? </resultMap>
可以發(fā)現(xiàn)ids加的位置是不一樣的,實(shí)體類中在outputField屬性下面,但resultMap中在其上面。然后測(cè)試數(shù)據(jù)中ids字段為null,查詢出來(lái)時(shí)卻發(fā)現(xiàn)ids的值和outputField的值是一樣的。但如果ids的字段有值,就可以正確賦值。
mybatis在生成目標(biāo)類進(jìn)行映射時(shí),會(huì)先檢查構(gòu)造函數(shù)聲明情況,但 如果Data注解和Builder注解一塊使用的話就只會(huì)生成全屬性參數(shù)構(gòu)造函數(shù),不會(huì)有默認(rèn)無(wú)參構(gòu)造函數(shù)。全屬性構(gòu)造函數(shù)的參數(shù)順序是和類中屬性聲明順序一致的
在把數(shù)據(jù)庫(kù)字段映射到實(shí)體類的時(shí)候發(fā)現(xiàn)實(shí)體類沒(méi)有默認(rèn)無(wú)參構(gòu)造函數(shù),就會(huì)把數(shù)據(jù)庫(kù)中的字段按照全屬性構(gòu)造函數(shù)參數(shù)的順序依次賦值給實(shí)體類的屬性。但如果實(shí)體類的屬性定義順序與數(shù)據(jù)庫(kù)中字段順序不一致,就會(huì)出現(xiàn)賦值錯(cuò)誤的情況。
然后再為outputField字段賦值時(shí)調(diào)用了set方法 這樣就出現(xiàn)了兩個(gè)不同名但同值的屬性。
解決辦法
1 修改屬性順序保持一致
2 為實(shí)體類加上@NoArgsConstructor和 @AllArgsConstructor注解 使其可以生成無(wú)參數(shù)構(gòu)造函數(shù)即可
之前生成時(shí) 順序都保持了一致,還真沒(méi)發(fā)現(xiàn)這個(gè)問(wèn)題
Mybatis使用resultMap時(shí)需注意
<resultMap id="baseMap" type="com.ei.medical.modules.model.EduEducationKnowledge">
<id column="id" property="id"/>
<result column="visitNumber" property="visitNumber"/>
<result column="patientName" property="patientName"/>
<result column="sendTime" property="sendTime"/>
<result column="wardCode" property="wardCode"/>
<result column="wardName" property="wardName"/>
<result column="categoryCode" property="categoryCode"/>
<result column="title" property="title"/>
<result column="content" property="content"/>
<result column="cover" property="cover"/>
</resultMap>
<select id="getAllBy" resultMap="baseMap">
SELECT
eer.visit_number as visitNumber,
eer.patient_name as patientName,
eer.send_time as sendTime,
eek.id as id,
eek.ward_code as wardCode,
eek.ward_name as wardName,
eek.category_code as categoryCode,
eek.title as title,
eek.content as content,
eek.cover as cover
FROM
edu_education_record AS eer,
edu_education_knowledge AS eek
WHERE
eer.education_knowledge_id=eek.id
</select>
如果是實(shí)體中是直接引用別的對(duì)象的具體參數(shù)字段,直接用原始方式就行
如果是實(shí)體中是list集合
<resultMap id="baseMap" type="com.ei.medical.modules.model.EduEducationKnowledge">
<id column="id" property="id"/>
<result column="visitNumber" property="visitNumber"/>
<result column="patientName" property="patientName"/>
<result column="sendTime" property="sendTime"/>
<result column="wardCode" property="wardCode"/>
<result column="wardName" property="wardName"/>
<result column="categoryCode" property="categoryCode"/>
<result column="title" property="title"/>
<result column="content" property="content"/>
<result column="cover" property="cover"/>
<collection property="pic" ofType="string">
<result column="pic"/>
</collection>
</resultMap>
<select id="getAllBy" resultMap="baseMap">
SELECT
eer.visit_number as visitNumber,
eer.patient_name as patientName,
eer.send_time as sendTime,
eek.id as id,
eek.ward_code as wardCode,
eek.ward_name as wardName,
eek.category_code as categoryCode,
eek.title as title,
eek.content as content,
eek.cover as cover
FROM
edu_education_record AS eer,
edu_education_knowledge AS eek
WHERE
eer.education_knowledge_id=eek.id
</select>
如果實(shí)體中引用的是別的對(duì)象,可以使用association 標(biāo)簽來(lái)寫(xiě)
<resultMap id="baseMap" type="com.ei.medical.modules.model.EduEducationKnowledge">
<id column="id" property="id"/>
<result column="wardCode" property="wardCode"/>
<result column="wardName" property="wardName"/>
<result column="categoryCode" property="categoryCode"/>
<result column="title" property="title"/>
<result column="content" property="content"/>
<result column="cover" property="cover"/>
<association property="eduEducationRecord" javaType="com.ei.medical.modules.model.EduEducationRecord">
<result column="visitNumber" property="visitNumber"/>
<result column="patientName" property="patientName"/>
<result column="sendTime" property="sendTime"/>
</association>
</resultMap>
<select id="getAllBy" resultMap="baseMap">
SELECT
eer.visit_number as visitNumber,
eer.patient_name as patientName,
eer.send_time as sendTime,
eek.id as id,
eek.ward_code as wardCode,
eek.ward_name as wardName,
eek.category_code as categoryCode,
eek.title as title,
eek.content as content,
eek.cover as cover
FROM
edu_education_record AS eer,
edu_education_knowledge AS eek
WHERE
eer.education_knowledge_id=eek.id
</select>
如果實(shí)體中是引用的別的對(duì)象的list集合,應(yīng)該使用collection 標(biāo)簽
<resultMap id="baseMap" type="com.ei.medical.modules.model.EduEducationKnowledge">
<id column="id" property="id"/>
<result column="wardCode" property="wardCode"/>
<result column="wardName" property="wardName"/>
<result column="categoryCode" property="categoryCode"/>
<result column="title" property="title"/>
<result column="content" property="content"/>
<result column="cover" property="cover"/>
<collection property="eduEducationRecordList" ofType="com.ei.medical.modules.model.EduEducationRecord">
<result column="visitNumber" property="visitNumber"/>
<result column="patientName" property="patientName"/>
<result column="sendTime" property="sendTime"/>
</collection>
</resultMap>
<select id="getAllBy" resultMap="baseMap">
SELECT
eer.visit_number as visitNumber,
eer.patient_name as patientName,
eer.send_time as sendTime,
eek.id as id,
eek.ward_code as wardCode,
eek.ward_name as wardName,
eek.category_code as categoryCode,
eek.title as title,
eek.content as content,
eek.cover as cover
FROM
edu_education_record AS eer,
edu_education_knowledge AS eek
WHERE
eer.education_knowledge_id=eek.id
</select>
tips:
使用resultMap的時(shí)候,應(yīng)該直接用as后面的字段名,即自己命的名字
如果沒(méi)有使用as的話,直接使用數(shù)據(jù)庫(kù)中原本的名字
resultMap中各個(gè)標(biāo)簽的含義

tips:
在一個(gè) resultMap 元素中,這些子元素出現(xiàn)的先后順序是有嚴(yán)格規(guī)定的,它們從前到后依次是:constructor–>id --> result–> association–>collection -->discriminator, 不然就會(huì)報(bào)錯(cuò)。
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Java Web 簡(jiǎn)單的分頁(yè)顯示實(shí)例代碼
這篇文章主要介紹了Java Web 簡(jiǎn)單的分頁(yè)顯示實(shí)例代碼的相關(guān)資料,本文通過(guò),計(jì)算總的頁(yè)數(shù)和查詢指定頁(yè)數(shù)據(jù)兩個(gè)方法實(shí)現(xiàn)分頁(yè)效果,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2016-06-06
javaweb實(shí)現(xiàn)簡(jiǎn)易郵件發(fā)送
這篇文章主要為大家詳細(xì)介紹了javaweb實(shí)現(xiàn)簡(jiǎn)易郵件發(fā)送,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-06-06
JAVA實(shí)現(xiàn)簡(jiǎn)單系統(tǒng)登陸注冊(cè)模塊
這篇文章主要介紹了一個(gè)簡(jiǎn)單完整的登陸注冊(cè)模塊的實(shí)現(xiàn)過(guò)程,文章條理清晰,在實(shí)現(xiàn)過(guò)程中加深了對(duì)相關(guān)概念的理解,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2015-07-07
Java微信公眾號(hào)開(kāi)發(fā)之通過(guò)微信公眾號(hào)獲取用戶信息
這篇文章主要介紹了Java微信公眾號(hào)開(kāi)發(fā)之通過(guò)微信公眾號(hào)獲取用戶信息,需要的朋友可以參考下2017-05-05
Java中private關(guān)鍵字詳細(xì)用法實(shí)例以及解釋
這篇文章主要給大家介紹了關(guān)于Java中private關(guān)鍵字詳細(xì)用法實(shí)例以及解釋的相關(guān)資料,在Java中private是一種訪問(wèn)修飾符,它可以用來(lái)控制類成員的訪問(wèn)權(quán)限,文中將用法介紹的非常詳細(xì),需要的朋友可以參考下2024-01-01
詳解如何在Spring?Security中自定義權(quán)限表達(dá)式
這篇文章主要和大家詳細(xì)介紹一下如何在Spring?Security中自定義權(quán)限表達(dá)式,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2022-07-07
SpringCloud遠(yuǎn)程服務(wù)調(diào)用實(shí)戰(zhàn)筆記
本文給大家介紹SpringCloud遠(yuǎn)程服務(wù)調(diào)用實(shí)戰(zhàn)筆記,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2021-11-11
Java正則表達(dá)式實(shí)現(xiàn)在文本中匹配查找換行符的方法【經(jīng)典實(shí)例】
這篇文章主要介紹了Java正則表達(dá)式實(shí)現(xiàn)在文本中匹配查找換行符的方法,結(jié)合具體實(shí)例分析了java正則匹配查找換行符的實(shí)現(xiàn)技巧與匹配模式相關(guān)操作注意事項(xiàng),需要的朋友可以參考下2017-04-04

